Print this diamond
J, 29 26 24 23 22 21 chars
,.(0&<#":)"+9-+/~|i:8
Thanks to FUZxxl for the "+
trick (I don't think I've ever used u"v
before, heh).
Explanation
i:8 "steps" vector: _8 _7 _6 ... _1 0 1 ... 7 8
| magnitude
+/~ outer product using +
9- inverts the diamond so that 9 is in the center
( )"+ for each digit:
# copy
0&< if positive then 1 else 0
": copies of the string representation of the digit
(in other words: filter out the strictly positive
digits, implicitly padding with spaces)
,. ravel each item of the result of the above
(necessary because the result after `#` turns each
scalar digit into a vector string)
APL (33 31)
A⍪1↓⊖A←A,0 1↓⌽A←⌽↑⌽¨⍴∘(1↓⎕D)¨⍳9
If spaces separating the numbers are allowed (as in the Mathematica entry), it can be shortened to 28 26:
A⍪1↓⊖A←A,0 1↓⌽A←⌽↑⌽∘⍕∘⍳¨⍳9
Explanation:
- (Long program:)
⍳9
: a list of the numbers 1 to 91↓⎕D
:⎕D
is the string '0123456789',1↓
removes the first element⍴∘(1↓⎕D)¨⍳9
: for each element N of⍳9
, take the first N elements from1↓⎕D
. This gives a list: ["1", "12", "123", ... "123456789"] as strings⌽¨
: reverse each element of this list. ["1", "21", "321"...](Short program:)
⍳¨⍳9
: the list of 1 to N, for N [1..9]. This gives a list [[1], [1,2], [1,2,3] ... [1,2,3,4,5,6,7,8,9]] as numbers.⌽∘⍕∘
: the reverse of string representation of each of these lists. ["1", "2 1"...]- (The same from now on:)
A←⌽↑
: makes a matrix from the list of lists, padding on the right with spaces, and then reverse that. This gives the upper quadrant of the diamond. It is stored in A.A←A,0 1↑⌽A
: A, with the reverse of A minus its first column attached to the right. This gives the upper half of the rectangle. This is then stored in A again.A⍪1↓⊖A
:⊖A
is A mirrored vertically (giving the lower half),1↓
removes the top row of the lower half andA⍪
is the upper half on top of1↓⊖A
.
Clojure, 191 179 bytes
#(loop[[r & s](range 18)h 1](print(apply str(repeat(if(< r 8)(- 8 r)(- r 8))\ )))(doseq[m(concat(range 1 h)(range h 0 -1))](print m))(println)(if s(recur s((if(< r 8)inc dec)h))))
-12 bytes by changing the outer doseq
to a loop
, which allowed me to get rid of the atom
(yay).
A double "for-loop". The outer loop (loop
) goes over each row, while the inner loop (doseq
) goes over each number in the row, which is in the range (concat (range 1 n) (range n 0 -1))
, where n
is the highest number in the row.
(defn diamond []
(let [spaces #(apply str (repeat % " "))] ; Shortcut function that produces % many spaces
(loop [[row-n & r-rows] (range 18) ; Deconstruct the row number from the range
high-n 1] ; Keep track of the highest number that should appear in the row
(let [top? (< row-n 8) ; Are we on the top of the diamond?
f (if top? inc dec) ; Decided if we should increment or decrement
n-spaces (if top? (- 8 row-n) (- row-n 8))] ; Calculate how many prefix-spaces to print
(print (spaces n-spaces)) ; Print prefix-spaces
(doseq [m (concat (range 1 high-n) (range high-n 0 -1))] ; Loop over the row of numbers
(print m)) ; Print the number
(println)
(if r-rows
(recur r-rows (f high-n)))))))
Due to a bug in the logic in my first attempt (accidentally inserting the prefix-spaces between each number instead), I managed to get this:
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 6 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
12345678987654321
1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 6 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
Not even correct ignoring the obvious bug, but it looked cool.