# Ragged Diamonds

diamond[n_Integer] :=
Table[1, {#}] & /@ (Range[n]~ Join~Range[n - 1, 1, -1])

diamond[5] // MatrixForm


How could a more functional, "tablefree", solution look like?

EDIT

But I'm looking for a 1-2-3-4-3-2-1 or 1-2-3-4-5-4-3-2-1 sequence which DiamondMatrix doesn't seem to offer.

-
@Öskå Thanks, but it's not "ragged", but filled with zeroes – eldo Aug 10 '14 at 19:09
@eldo I believe number of roms should equal 2n-1. most of answerer did not consider this issue. – Algohi Aug 10 '14 at 19:46
@Algohi You posted an answer approx 20 minutes ago which gave what I expected. Why did you delete it? Please repost! – eldo Aug 10 '14 at 19:49
DeleteCases[0] /@ DiamondMatrix[10] ? – Szabolcs Aug 10 '14 at 20:02
@eldo, I was having some problems with pc and then kguler did something similar and I did not want to repeat. – Algohi Aug 10 '14 at 23:06

Not much to add to the existing answers except that my favorite method to convert lists of natural numbers to all ones is x^0 therefore:

f[n_] := Range[n - Abs @ Range[1-n, n-1]]^0


Also I don't believe anyone has yet used Diagonal:

f2[n_] := With[{m = BoxMatrix[(n - 1)/2]}, Array[m ~Diagonal~ # &, 2 n - 1, 1 - n]]

-
Your first solution clearly shows why everybody (including myself) should respect the 48-hours-rule before accepting :) – eldo Aug 11 '14 at 22:35
@eldo Not that I expect you to but you can change the Accept if you wish. I agree however that it's best not to Accept too quickly as I believe it reduces interest in your Question. – Mr.Wizard Aug 11 '14 at 23:11
My "mathematical conscience" tells me that I must change the acceptance because of your first solution. – eldo Aug 11 '14 at 23:26
@eldo Well, thank you. :-) – Mr.Wizard Aug 11 '14 at 23:28
Since in this case there are no negative numbers, I would use UnitStep to get the ones – RunnyKine Aug 12 '14 at 0:29

I know I'm a little bit late to the party but here's a way to generate the ragged diamond using DiamondMatrix directly:

(* Generate double diamond surrounded by zeros using DiamondMatrix*)
diamondWithin = DiamondMatrix[{4, 5}, {9, 10}];
(* Trim the zeros and resulting empty lists (if any) *)
trimZero = diamondWithin //. {0 :> Sequence[], {} :> Sequence[]};
(* Half the number of 1's in each row *)
goalDiamond = trimZero /. {x__, x__} :> {x};

(* Display *)
{diamondWithin // MatrixForm[# /. {1 :> Style[1, Red]}] &,
MatrixForm@trimZero, MatrixForm@goalDiamond} //
TableForm[{#},
None, {"diamondWithin", "trimZero", "goalDiamond"}},
TableAlignments -> Center] &


## One-liner

DiamondMatrix[{4, 5}, {9, 10}] //.
{0 :> Sequence[], {} :> Sequence[]} /.
{x__, x__} :> {x} // MatrixForm


## A note about DiamondMatrix

I found the documentation of this function very vague. The only useful thing I could find was the last example where the function was used like so: DiamondMatrix[{a, b}, {c, d}]. After playing around with changing the values of these variables, it seems to me that changing a and b will affect the height and width (in that order) of the inner diamond, while changing c and d will change the height and width of the entire matrix that contains the diamond.

I'd built a Manipulate to experiment with using the function to create the desired matrix. Note that an odd-width/height matrix will contain only odd-width/height diamond (try it out and you'll see). In this case, the double diamond has a width of 10 (even) and height of 9 (odd). Compare these dimensions to just 5 and 9 in the original diamond.

Therefore, I will choose a large matrix with odd height and even width, say 17 x 14, by changing c and d. I then changed a and b to get the desired dimension of the inner double diamond (9 x 10; note that 9 and 17 are both odd, while 10 and 14 both even).

After that you can choose to resize the overall matrix down to a smaller size by lowering c and d (but it really doesn't matter since post-processing will remove anything surrounding the diamond anyway).

Lastly, note that previous answers that involved DiamondMatrix did not generate truly "ragged" diamonds, but rather 1, 3, 5, and so on, diamonds.

Manipulate[Module[{m, displaym, diamond, mh, mw, dh, dw},
m = DiamondMatrix[{a, b}, {c, d}];
displaym =
m /. {1 :> Style[1, Red], 0 :> Style[0, Lighter[Gray, 0.7]]};
diamond = DeleteCases[m, 0, {2}] // DeleteCases[#, {}, {1}] &;
{mh, mw} = Dimensions@m;
{dh, dw} = {Length@diamond, Max[Length /@ diamond]};

(* Evaluate mExtract in another cell after you're done manipulating to get the matrix*)
mExtract = m;

(* Display *)
{{Style[
"DiamondMatrix[" <> ToString@{a, b} <> ", " <> ToString@{c, d} <>
"]", Blue], SpanFromLeft},
{Style["Diamond:", Red],
Grid@Transpose@{Style[#, Red] & /@ {"Height", "Width"},
Style[#, Red] & /@ {dh, dw}}, "Matrix:",
Grid@Transpose@{{"Height", "Width"}, {mh, mw}}},
{MatrixForm@displaym, SpanFromLeft}} //
Grid[#, Frame -> All, Spacings -> {1, 1},
Dividers -> {{2 -> False, 4 -> False}, Automatic}] &],

{{a, 5}, 1, 10, 1}, {{b, 5}, 1, 10, 1}, {{c, 10}, 1, 20, 1}, {{d, 10}, 1, 20, 1}]


## Another way to use DiamondMatrix

The diamond matrices in @Szabolcs and @paw's answers generate 1,3,5-diamonds and not 1,2,3-diamond like you wanted. However, a little modification of that matrix will generate the desired diamond.

This is done by observing that a row in a 1,3,5-diamond (let's say the row of length 5) differs from the corresponding row in a 1,2,3-diamond (that means the row of length 3) by half of Length[row in 1,3,5-diamond] - 1. In other words, 1 + 2 = 3, but 1 + 2(2) = 5.

diamond135 = DeleteCases[DiamondMatrix[4], 0, {2}];
diamond135 // MatrixForm


diamond123 = diamond135 /. x : {1 ..} :> ConstantArray[1, Length@x - (Length@x - 1)/2];
diamond123 // MatrixForm


## One-liner

DiamondMatrix[4] /. {0 :> Sequence[]} /.
x : {1 ..} :> ConstantArray[1, Length@x - (Length@x - 1)/2] // MatrixForm

-
Thank you very much. It's not only fun playing with but also instructive :) – eldo Aug 11 '14 at 15:42
Thanks! Glad you liked it. I added to my answer another way of using DiamondMatrix. – seismatica Aug 11 '14 at 20:23

Defining a helper function for tidiness:

diamondcounts[n_] := Range[n] ~Join~ Range[n - 1, 1, -1]


You could use ConstantArray and Map

ConstantArray[1, #] & /@ diamondcounts[n]


But personally I think Table is a rather nice choice here:

Table[1, {i, diamondcounts[n]}, {i}]

-
I like Table[1, {i, diamondcounts[n]}, {i}]. But why does it function? The i is nowhere defined, is it? – eldo Aug 10 '14 at 21:05
@eldo, i is just the iterator variable. In the outer loop it acquires values from diamondcounts[n] and then the inner loop runs i times. – Simon Woods Aug 11 '14 at 8:48

Using ArrayPad to reflect a pyramid matrix:

diamond[n_] := ArrayPad[ConstantArray[1, #] & /@ Range[n], {{0, n - 1}}, "Reflected"]
diamond[5] // MatrixForm


-
+1 Clever use of ArrayPad – Simon Woods Aug 10 '14 at 20:17

Here are two different methods based on Array:

diamond[n_] := With[{a = ConstantArray[1, #] &}, Array[a, n]~ Join ~Reverse@Array[a, n - 1]]


OR

diamond[n_]:= Array[Array[1 &, #] &, {n}] ~ Join ~ Reverse[Array[Array[1 &, #] &, {n-1}]]

diamond[5] // MatrixForm


-
I get with diamond[n_] := Array[ConstantArray[1, #] &, n]~Join~ Reverse@Array[ConstantArray[1, #] &, n - 1] an error message: "SetDelayed::write: Tag Function in ((ConstantArray[1,#1]&)/@Join[Range[t],{#1+1},Reverse[Range[#1]]]&)[n_] is Protected." – eldo Aug 10 '14 at 21:19
@eldo, I don't know why you would get that. It works fine for me. Maybe start a new kernel. – RunnyKine Aug 10 '14 at 21:21
Thanks, now it works. A little bit strange though, because before my first attempt I executed Clear["Global*"] – eldo Aug 10 '14 at 21:27
@eldo. Good, glad it works. – RunnyKine Aug 10 '14 at 21:27
Since I would like to accept this answer please reformulate: diamond[n_] := With[{a = ConstantArray[1, #] &}, Array[a, n]~Join~Reverse@Array[a, n - 1]] – eldo Aug 10 '14 at 21:43

Here is a FoldList approach:

diamond[n_] := Rest@FoldList[ConstantArray[1, #2] &, 0, Range[n]~Join~Range[n - 1, 1, -1]]


Then:

diamond[6] // MatrixForm


-
diamond[n_] := 1 & /@ Range[#] & /@ (Range[n]~Join~Reverse@Range[n - 1]);


or

diamond[n_] := Array[1 &, n - Abs[#]] & /@ Range[1 - n, n - 1];

diamond[10]//MatrixForm


-

A helper function

PeekRange[n_] := With[{r = Range @ n}, r ~ Join ~ Reverse @ Most @ r]


Partition:

diamond1[n_] := Partition[ConstantArray[1, n], n, 1, {-1, 1}, {}]


ListConvolve:

diamond2[n_] := ConstantArray @@@ ListConvolve[{1}, PeekRange @ n, 1, 0, List]


ArrayReshape:

diamond3[n_] := Map[Flatten[ArrayReshape[ConstantArray[1, n], {#, 1}]] &, PeekRange @ n]


ReplaceList:

diamond4[n_] :=
Map[First, #]~Join~Rest@Map[Last, #] &[
ReplaceList[ConstantArray[1, n + 1], {x__, y__} :> {{x}, {y}}]]


All give with n = 5

-
@Öska Thanks, will remember to give links in the future :) – eldo Aug 11 '14 at 15:47
It's just a good thing to give links while enumerating the functions IMO :) – Öskå Aug 11 '14 at 15:49

Many ways possible

diamond = Function[ConstantArray[1, #] & /@ Join[Range@t, {# + 1}, Reverse@Range@#] // MatrixForm]
diamond@5


more or less complicate, with SparseArray

diamond =
Function[SparseArray[{i_, j_} /; i >= j -> 1, {#, #}]~Join~
Reverse@SparseArray[{i_, j_} /; i >= j -> 1, {#, #}] // Normal //
ReplaceAll[#, 0 -> Sequence[]] & //
Column[#, Alignment -> Center] &]

diamond@5


or just pure "1"

diamond =
Function[Array[Row@Array[" 1 " &, #] &, {# + 1}]~Join~
Reverse@Array[Row@Array[" 1 " &, #] &, {#}] //
Column[#, Alignment -> Center] &]
diamond@5


without function

a = Array[1 &, #] &;
Array[a, {6}]~Join~ Reverse@Array[a, {5}] // MatrixForm
Array[a, {6}]~Join~ Reverse@Array[a, {5}] //
Column[#, Alignment -> Center] &


or a squareDiamond (did it also)

DiamondMatrix@10 /. (0 -> Sequence[]) // MatrixForm


and more and more ...

-
foo = Composition[Sign, Range, Range];
bar = Composition[Reverse, Most, foo];
dmnd0 = Join @@ Through[{foo, bar}[#]] &;

dmnd1 = With[{m = Unitize @ Range[Range[#]]}, Join @@ {m, Reverse @ Most @ m}] &

dmnd2 = With[{r = Join[Range[0, #-1], Range[#-2, 0, -1]]}, ArrayPad[{1}, {0, #}, 1]& /@ r] &

dmnd3 = Join @@ {#, Reverse[Most@#]} &@NestList[Append[#1, 1] &, {1}, # - 1] &

dmnd4 = Join @@{Reverse[Rest@#], #} &@ NestList[Drop[#, 1] &, Array[1 &, {#}], # - 1] &

dmnd0[5] //MatrixForm


dmnd0[5] == dmnd1[5] == dmnd2[5] == dmnd3[5] == dmnd4[5]
(* True *)

-

DeleteCases[#, 0] & /@ DiamondMatrix[10]
`