Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

This question has been spreading like a virus in my office. There are quite a variety of approaches:

Print the following:

        1
       121
      12321
     1234321
    123454321
   12345654321
  1234567654321
 123456787654321
12345678987654321
 123456787654321
  1234567654321
   12345654321
    123454321
     1234321
      12321
       121
        1
share|improve this question
2  
What is the winning criterion ? And is this a challenge or a golf ? –  Paul R Oct 12 '12 at 15:33
7  
I read "kolmogorov-complexity" as "code-golf". –  David Carraher Oct 12 '12 at 16:44
1  
@DavidCarraher "kolmogorov-complexity" was edited in after the question was asked. The original questioner has not specified the winning criteria yet. –  Gareth Oct 12 '12 at 20:56
    
@Gareth My comment was made after the "kolmogorov-complexity" tag was added but before the "code-golf" tag was added. At that time people were still be asking whether it was a code-golf question. –  David Carraher Oct 12 '12 at 22:00
3  
perlmonks.com/?node_id=891559 has perl solutions. –  Zsbán Ambrus Oct 20 '12 at 19:51

39 Answers 39

up vote 4 down vote accepted

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)
share|improve this answer
    
Instead of "0], write "+. –  FUZxxl Apr 11 at 10:26
    
For one less character, write ,.0(<#":)"+9-+/~|i:8 –  FUZxxl Apr 11 at 13:24
1  
Here is your solution translated to 25 characters of APL: ⍪↑{(0<⍵)/⍕⍵}¨9-∘.+⍨|9-⍳17 –  FUZxxl Apr 11 at 13:44

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 9
  • 1↓⎕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 from 1↓⎕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 and A⍪ is the upper half on top of 1↓⊖A.
share|improve this answer
5  
+1 Amazing. Could you translate it for us APL illiterates? –  David Carraher Oct 12 '12 at 19:36
2  
Shouldn't non-ascii code be counted in UTF-8 instead of code-points? This would push APL closer to his earthly relatives. –  Jan Dvorak Mar 23 '13 at 5:39
2  
@JanDvorak No, since there is an APL code page, which fits the entire character set into a single byte. But I think you've probably figured this out at some point since 2013. ;) –  Martin Büttner Jan 25 at 0:34

Mathematica 83 49 43 54

Grid[Sum[k~DiamondMatrix~17, {k, 0, 8}] /. 0 -> "", Spacings -> 0]

formatting improved


Analysis

The principal part of the code, Sum[DiamondMatrix[k, 17], {k, 0, 8}], can be checked on WolframAlpha.

The following shows the underlying logic of the approach, on a smaller scale.

a = 0~DiamondMatrix~5;
b = 1~DiamondMatrix~5;
c = 2~DiamondMatrix~5;
d = a + b + c;
e = d /. 0 -> "";
Grid /@ {a, b, c, d, e}

grids

share|improve this answer
    
David, you beat me this time! :-) –  Mr.Wizard Oct 21 '12 at 15:29
    
Another try (55 chars): f = Table[# - Abs@k, {k, -8, 8}] &; f[f[9]] /. n_ /; n < 1 -> "" // Grid –  David Carraher Mar 22 '13 at 17:56
    
Still another (71 chars): Table[9 - ManhattanDistance[{9, 10}, {j, k}], {j, 18}, {k, 18}] /. n_ /; n < 1 -> "" // Grid –  David Carraher Mar 22 '13 at 17:57
2  
Grid@#@#@9&[Table[#-Abs@k,{k,-8,8}]&]/.n_/;n<1->"" 50 chars. –  chyaong Mar 23 '13 at 4:26
    
A visual display of the code: ArrayPlot[Sum[k~DiamondMatrix~17, {k, 0, 8}], AspectRatio -> 2] –  David Carraher Nov 23 '13 at 15:53

GolfScript, 33 31 30 characters

Another GolfScript solution

17,{8-abs." "*10@-,1>.-1%1>n}%

Thank you to @PeterTaylor for another char.

Previos versions:

17,{8-abs" "*9,{)+}/9<.-1%1>+}%n*

(run online)

17,{8-abs" "*9,{)+}/9<.-1%1>n}%
share|improve this answer
1  
You don't need the trailing spaces (the text in the question doesn't have them), so you can skip adding the numbers to the spaces and save one char as 17,{8-abs." "*10@-,1>.-1%1>n}% –  Peter Taylor Mar 28 '13 at 16:21

Python 72 69 67 61

Not clever:

s=str(111111111**2)
for i in map(int,s):print'%8s'%s[:i-1]+s[-i:]
share|improve this answer
1  
doesn't work in Python 3+, which requires parens around the arguments to print :( –  Griffin Oct 12 '12 at 18:27
4  
@Griffin: In code golf I choose Python 2 or Python 3 depending on whether I need print to be a function. –  Steven Rumbalski Oct 12 '12 at 19:29
2  
s=`0x2bdc546291f4b1` –  gnibbler Oct 14 '12 at 1:32
1  
@gnibbler. Very clever suggestion. Unfortunately, the repr of that hexadecimal includes a trailing 'L'. –  Steven Rumbalski Oct 15 '12 at 14:51
    
How about `` s=111111111**2 ``? It works for me with 2.7.5 - what version are you running? –  Daniel Nov 19 '13 at 19:37

C, 79 chars

v;main(i){for(;i<307;putchar(i++%18?v>8?32:57-v:10))v=abs(i%18-9)+abs(i/18-8);}
share|improve this answer
    
Explanation please? –  Lucas Henrique Apr 12 at 16:35

Javascript, 114

My first entry on Codegolf!

for(l=n=1;l<18;n-=2*(++l>9)-1,console.log(s+z)){for(x=n,s="";x<9;x++)z=s+=" ";for(x=v=1;x<2*n;v-=2*(++x>n)-1)s+=v}

If this can be shortened any further, please comment :)

share|improve this answer

Mathematica 55 50 45 41 38

(10^{9-Abs@Range[-8,8]}-1)^2/81//Grid

Grid[(10^Array[{9}-Abs[#-9]&,17]-1)^2/81]

Mathematica graphics

share|improve this answer
1  
Very nice work. –  David Carraher Mar 22 '13 at 17:17
    
@DavidCarraher Thank you :D –  chyaong Mar 23 '13 at 4:05
    
I echo David's remark. How did you come up with this? –  Mr.Wizard Mar 27 '13 at 7:02
    
@Mr.Wizard Just carefully observed and many tries. –  chyaong Mar 27 '13 at 16:40
    
May I update your answer with the shorter modification I wrote? –  Mr.Wizard Mar 27 '13 at 21:49

PHP, 92 90 characters

<?for($a=-8;$a<9;$a++){for($b=-8;$b<9;){$c=abs($a)+abs($b++);echo$c>8?" ":9-$c;}echo"\n";}

Calculates and prints the Manhattan distance of the position from the centre. Prints a space if it's less than 1.

An anonymous user suggested the following improvement (84 characters):

<?for($a=-8;$a<9;$a++,print~õ)for($b=-8;$b<9;print$c>8?~ß:9-$c)$c=abs($a)+abs($b++);
share|improve this answer
    
2nd one doesn't work. –  Christian Mar 22 '13 at 4:30

Python, 60 59

for n in`111111111**2`:print`int('1'*int(n))**2`.center(17)

Abuses backticks and repunits.

share|improve this answer
    
The space after in keyword can be removed, just like you did with print keyboard. –  xfix Oct 23 '12 at 17:02
    
@GlitchMr: Thanks! Updated. –  nneonneo Oct 23 '12 at 17:06
    
I get an extra L in the middle seven lines of output. –  Steven Rumbalski Mar 28 '13 at 14:56
    
You shouldn't...what version of Python are you using? –  nneonneo Mar 28 '13 at 15:07

Common Lisp, 113 characters

(defun x(n)(if(= n 0)1(+(expt 10 n)(x(1- n)))))(dotimes(n 17)(format t"~17:@<~d~>~%"(expt(x(- 8(abs(- n 8))))2)))

First I noticed that the elements of the diamond could be expressed like so:

  1   =   1 ^ 2
 121  =  11 ^ 2
12321 = 111 ^ 2

etc.

x recursively calculates the base (1, 11, 111, etc), which is squared, and then printed centered by format. To make the numbers go up to the highest term and back down again I used (- 8 (abs (- n 8))) to avoid a second loop

share|improve this answer

GolfScript, 36 chars

Assuming that this is meant as a challenge, here's a basic GolfScript solution:

9,.);\-1%+:a{a{1$+7-.0>\" "if}%\;n}%
share|improve this answer

R, 71 characters

For the records:

s=c(1:9,8:1);for(i in s)cat(rep(" ",9-i),s[0:i],s[(i-1):0],"\n",sep="")
share|improve this answer
    
+1 - can save a few with message(rep(" ",9-i),s[c(1:i,i:1-1)]) –  flodel Apr 11 at 17:14

Ruby, 76 characters

def f(a)a+a.reverse[1..-1]end;puts f [*1..9].map{|i|f([*1..i]*'').center 17}

Improvements welcome. :)

share|improve this answer
    
69 chars: f=->x{[*1..x]+[*1...x].reverse};puts f[9].map{|i|(f[i]*'').center 17} –  Patrick Oscity Nov 5 '12 at 21:11

k (64 50 chars)

-1'(::;1_|:)@\:((|!9)#'" "),'$i*i:"J"$(1+!9)#'"1";

Old method:

-1',/(::;1_|:)@\:((|!9)#\:" "),',/'+(::;1_'|:')@\:i#\:,/$i:1+!9;

share|improve this answer

JavaScript, 81

for(i=9;--i+9;console.log(s))for(j=9;j;s=j--^9?k>0?k+s+k:" "+s:k+"")k=i<0?j+i:j-i
share|improve this answer

PowerShell: 92 84 45 (2 options)

1..8+9..1|%{' '*(9-$_)+[int64]($x='1'*$_)*$x}
1..9+8..1|%{' '*(9-$_)+[int64]($x='1'*$_)*$x}

Thanks to Strigoides for the hint to use 1^2,11^2,111^2...


Shaved some characters by:

  • Eliminating $w.
  • Nested the definition of $x in place of its first use.
  • Took some clues from Rynant's solution:
    • Combined the integer arrays with + instead of , which allows elimination of the parenthesis around the arrays and a layer of nesting in the loops.
    • Used 9-$_ to calculate the length of spaces needed, instead of more complicated maths and object methods. This also eliminated the need for $y.

Explanation:

1..8+9..1 or 1..9+8..1 generates an array of integers ascending from 1 to 9 then descending back to 1.

|%{...} pipes the integer array into a ForEach-Object loop via the built-in alias %.

' '*(9-$_)+ subtracts the current integer from 9, then creates a string of that many spaces at the start of the output for this line.

[int64]($x='1'*$_)*$x defines $x as a string of 1s as long as the current integer is large. Then it's converted to int64 (required to properly output 1111111112 without using E notation) and squared.

enter image description here

share|improve this answer

Perl 56 54 characters

Added 1 char for the -p switch.

Uses squared repunits to generate the sequence.

s//12345678987654321/;s|(.)|$/.$"x(9-$1).(1x$1)**2|eg
share|improve this answer

Groovy 77 75

i=(-8..9);i.each{a->i.each{c=a.abs()+it.abs();print c>8?' ':9-c};println""}

old version:

(-8..9).each{a->(-8..9).each{c=a.abs()+it.abs();print c>8?' ':9-c};println""}
share|improve this answer

Scala - 86 characters

val a="543210/.-./012345";for(i<-a){for(j<-a;k=99-i-j)print(if(k<1)" "else k);println}
share|improve this answer

Javascript, 137

With recursion:

function p(l,n,s){for(i=l;i;s+=" ",i--);for(i=1;i<=n;s+=i++);for(i-=2;i>0;s+=i--);return(s+="\n")+(l?p(l-1,n+1,"")+s:"")}alert(p(8,1,""))

First time on CG :)

Or 118

If I can find a JS implementation that executes 111111111**2 with higher precision.
(Here: 12345678987654320).

a="1",o="\n";for(i=0;i<9;i++,o+="         ".substr(i)+a*a+"\n",a+="1");for(i=8;i;i--)o+=o.split("\n")[i]+"\n";alert(o)
share|improve this answer

GolfScript (27 chars)

17,{8-abs' '*1`9*1$,>~.*n}/

or

17,{8-abs' '*.1`9*+9<~.*n}/

Both work by building a suitable repunit as a string and then converting to int and squaring to get a Demlo number.

share|improve this answer

Perl, 43+1

adding +1 for -E which is required for say

say$"x(9-$_).(1x$_)**2for 1..9,reverse 1..8

edit: shortened a bit

share|improve this answer

Python, 65

for i in map(int,str(int('1'*9)**2)):print' '*(9-i),int('1'*i)**2
share|improve this answer

Perl 6, 42 41 chars

say " "x 9-$_,(1 x$_)**2 for 1..9,(8...1)

Hey, it's one two characters shorter compared to Perl 5 - Perl 6 needs more whitespace than Perl 5, but it's still shorter.

share|improve this answer

Javascript, 129* 126

for(i=1;i<18;i++){s="";a=Math.abs(9-i);for(j=0;j<a;j++)s+=" ";for(k=a+1;k<=9;k++)s+=k-a;for(l=8;l>a;l--)s+=l-a;console.log(s)}

Includes suggestion from Shmiddty in comments. Original preserved below:

for(i=1;i<18;i++){s="";a=Math.abs(9-i);for(j=0;j<a;j++){s+=" "}for(k=a+1;k<=9;k++){s+=k-a}for(l=8;l>a;l--){s+=l-a}console.log(s)}

I'm sure this could be condensed further, but darned if I know how. :P

share|improve this answer
    
This gets the JS nod. It multiplies correctly. –  Christian Mar 22 '13 at 4:37
1  
Instead of wrapping your for loops in brackets, use a semicolon. eg: for(j=0;j<a;j++)s+=" ";for(k... –  Shmiddty Mar 22 '13 at 18:59
    
Thank you for pointing that out, @Shmiddty. I've adjusted the snippet. –  joequincy Mar 22 '13 at 21:56

APL (40)

r←{⍵,1↓⌽⍵}
{⎕←⍵,⍨' '⍴⍨(2×10-⌈/⍵)}¨r¨r⍳¨⍳9

I guess I'm not beating marinus. :p

share|improve this answer

PowerShell, 49 48

1..9+8..1|%{"  "*(9-$_)+(1..$_+($_-1)..0|?{$_})}
share|improve this answer
    
Nice solution, though it has a lot of spacing not called for in the challenge. Helped me trim mine down to half its original size. –  Iszi Nov 24 '13 at 2:24

APL, 24 chars

⍉⊃{⍕⍵↑⍨⍵>0}¨9-∘.+⍨|9-⍳17

Tested in Nars2000 and Dyalog (requires ⎕ML←3 in the latter.)

Explanation

                     ⍳17    starting with the naturals up to 17
                  |9-       generate the numbers from 8 to 0 and back to 8
              ∘.+⍨          make a table of their sum (with 0 in the middle)
            9-              turn it into a diamond with 9 in the middle
  {       }¨                for each number
    ⍵↑⍨⍵>0                  keep it only if it's positive
   ⍕                        then convert the result, if any, to a string
⍉⊃                          disclose the nested array and adjust the dimensions

The last step transposes the result, whose shape is 17 17 1 (because of the disclose of nested strings) into 1 17 17, which gets printed like a plain 17 17.

Output

⍉⊃{⍕⍵↑⍨⍵>0}¨9-∘.+⍨|9-⍳17
        1        
       121       
      12321      
     1234321     
    123454321    
   12345654321   
  1234567654321  
 123456787654321 
12345678987654321
 123456787654321 
  1234567654321  
   12345654321   
    123454321    
     1234321     
      12321      
       121       
        1        
share|improve this answer

Bash, 126 109 87 chars

87:

q()(printf %$[9+$1%9]s\\n $[$2*$2];[ 7 -lt $1 ]||(q $[$1+1] ${2}1;q $[$1+9] $2))
q 0 1

As it usually goes, changing from iterative to recursive solution helps us win additional bytes.

Meaning of parameters to q:

$1 How much to remove from 8 to get the number of spaces in the beginning. Note value modulo 9 counts here (actual value is also a hint to quit recursion).

$2 The current chain of 1s to be squared and output by printf.

The modus operandi is:

  1. output the sequence (ie. if $2 is 11111, output 123454321)
  2. (if not yet at 12..9..21 - the recursive step)

    2.1. output the next sequence (here: 111111 > $2 , output 12345654321

    2.2. output the sequence once again (123454321).

In the step 2.2 , we pass (indent value + 9) instead of indent value however, so that the algoritm "knows" we are printing the row for the second time. Without this, the [ 7 -lt $1 ] would be false, causing us to retrigger the recursive step 1. This would never finish then.

The recursion goes like this:

q 0 1:                          1
 q 1 11:                       121
  q 2 111:                    12321
   q 3 1111:                 1234321
    q  4 11111:             123454321
     q  5 111111:          12345654321
      q  6 1111111:       1234567654321
       q  7 11111111:    123456787654321
        q  8 111111111: 12345678987654321
        q 16 11111111:   123456787654321
       q 15 1111111:      1234567654321
      q 14 111111:         12345654321
     q 13 11111:            123454321
    q 12 1111:               1234321
   q 11 111:                  12321
  q 10 11:                     121
 q  9 1:                        1


109:

p()(printf "%$[8+i]s\n" $[k*k])
k=;for i in `seq 9`;do k+=1;p;done;for i in `seq 8 -1 1`;do k=${k:1};p;done;

"k+=1" is much cheaper as k=$[10*k+1] , and for k being a string of ones it's the same. Same goes for ${k:1} and $[k/10] .


126:

p() (printf "%$[$1+i]s\n" $[k*k];)
k=1;for i in `seq 8`;do p 8;k=$[10*k+1];done;for i in `seq 8 -1 0`;do p 9;k=$[k/10];done;

I guess there may be even shorter solution, but weather is glorious, I can't stand sitting in front of computer any more :).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.