http://www.perlmonks.org?node_id=891559

One geeky afternoon at work, we challenged each other to write the smallest possible program in any language to print a diamond made out of numbers, from 1 to a maximum of 9.

For example a diamond of 1 would just be 1.

A diamond of 2 would be:

1 121 1

A diamond of 3 would be:

1 121 12321 121 1
And you get the idea for all the way up to 9...

One of them wrote several lines of c# code. Another wrote a really long one line of code that had predefined outputs. So I entered the prizeless contest, and I decided to use Perl.

I'm sure there is a way to make a long and ugly one liner out of this, but I wanted to share what I came up with after reading chapter 1 and 2 of Learning Perl.

Enjoy!

#!/usr/bin/perl print 'Diamond size (1-9): '; chomp($diamondSize = <STDIN>); foreach $i(@i = (1..$diamondSize, reverse (1..$diamondSize-1))) { print ' ' x ($diamondSize - $i), (@d ="1".."$i"), (reverse @d[ +0..$#d-1]), "\n"; }

Replies are listed 'Best First'.
Re: Diamonds for fun
by BrowserUk (Patriarch) on Mar 05, 2011 at 11:10 UTC

    Golf:68. How to get rid of those reverses?

    perl -E"$n=pop;say' 'x($n-$_),1..$_,reverse 1..$_-1for 1..$n,reverse 1 +..$n-1" 9

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Had to:
      perl -e '$n=pop; print "\n", " "x($n-$_),1..$_,reverse 1..$_-1, for 1. +.$n,reverse 1..$n-1' 9
      for 5.8 ish ... seems like there's a marvelous recursive solution but my brain is too small to find it.

      a

      Golf:56 :)
      perl -E'$_=pop;sub r{1..$_,reverse 1..$_-1}say" "x(9-$_),r for r' 9 1 121 12321 1234321 123454321 12345654321 1234567654321 123456787654321 12345678987654321 123456787654321 1234567654321 12345654321 123454321 1234321 12321 121 1

      Cheers Rolf

        Combining with other posts here, golf:55

        perl -E'$_=pop;sub r{1..$_,reverse 1..$_-1}say$"x(9-$_),r for r' 9

        Enjoy, Have FUN! H.Merijn
Re: Diamonds for fun
by ambrus (Abbot) on Mar 07, 2011 at 14:13 UTC

    I'm quite sure this can be golfed further, but as it seems shorter than the above solutions I must post it.

    perl -le 'printf"%*s\n",$t+$_,(1x$_)**2for(1x($t=pop))**2=~/./g' 9

    Update: see also Christmas Tree.

    Update: one character shorter:

    perl -e 'printf"%*s\n",$t+$_,(1x$_)**2for(1x($t=pop))**2=~/./g' 9

    Somewhat shorter:

    perl -le 'print" "x($t-$_),(1x$_)**2for(1x($t=pop))**2=~/./g' 9

    Update 2012-03-14: and see Spiraling integers for yet another arrangement of numbers.

      You can shave 3 off your lowest score using perl 5.10:
      # score = 53 # 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890123456789 perl -E'say" "x($t-$_),(1x$_)**2for(1x($t=pop))**2=~/./g' 9
      update due to hbm's observation:
      # score = 52 # 1 2 3 4 5 # 12345678901234567890123456789012345678901234567890123456789 perl -E'say$"x($t-$_),(1x$_)**2for(1x($t=pop))**2=~/./g' 9

      Squaring a string of ones ((1x$_)**2) is very clever! This works for me up to 8, but 9 fails (because 111111111**2 = 1.23456789876543e+16). (Same for toolic's solution below...)

      You can save one more character with $" instead of " ".

        It works for 9 on a 64 bit system, which is why I didn't notice it's broken, but it is indeed broken on 64 bit systems.

        You could try to fix it with something like this, but as is that's too long and I don't feel much like golfing it now.

        perl -e 'printf"%*.0f\n",$t+abs,(1x abs)**2for 1..($t=pop),1-$t..-1' 9
Re: Diamonds for fun
by repellent (Priest) on Mar 06, 2011 at 09:26 UTC
    Golfed at 83.
    perl -E'$n=pop;say$x[@x]=$p=" "x($n-$_).(1x(2*$_-1)+$p*10)for 1..$n;sa +y for@x[map-$_,2..@x]' 9
Re: Diamonds for fun
by ambrus (Abbot) on Oct 20, 2012 at 19:52 UTC
Re: Diamonds for fun
by LanX (Saint) on May 04, 2011 at 12:35 UTC
    perl -e'$"="";$x=pop;@x=reverse(1..$x);print " "x($x-$_),"@x[@x[1..$_] +]@x[$x+1-$_..$x]\n"for@x[@x],@x' 9 1 121 12321 1234321 123454321 12345654321 1234567654321 123456787654321 12345678987654321 123456787654321 1234567654321 12345654321 123454321 1234321 12321 121 1

    could be shortened!

    have fun deobfuscating! :)

    Cheers Rolf