28
\$\begingroup\$

I figured an "arch" was the best way to describe this pattern of numbers:

1234567887654321
1234567  7654321
123456    654321
12345      54321
1234        4321
123          321
12            21
1              1

Formally defined, each line consists of the numbers 1 through 9-n, (n-1)*2 spaces, and the numbers 9-n through 1 (where n is the current line).

Your task is to write, using the shortest code possible, a small script/program that prints the above pattern subject to the following restrictions:

  1. You may not hardcode the entire pattern. You may only hardcode a single line of the pattern at most.
  2. Your program must print a newline (any combination of \n or \r) at the end of each line.

Ready... set.... go!

\$\endgroup\$
  • 1
    \$\begingroup\$ Additional little trick would be available with upper line 123456787654321 as it equals to 11111111^2 ;-) \$\endgroup\$ – Egor Skriptunoff May 12 '13 at 13:57
  • 3
    \$\begingroup\$ @EgorSkriptunoff 11111111^2 == 123465787654321 != 1234567887654321 (notice the repeated 8) \$\endgroup\$ – Bob May 12 '13 at 14:43
  • \$\begingroup\$ This is sort-of the inverse of Print this diamond \$\endgroup\$ – Peter Taylor May 14 '13 at 9:23
  • 6
    \$\begingroup\$ It looks rather like a curtain. \$\endgroup\$ – Volatility May 15 '13 at 8:53

36 Answers 36

22
\$\begingroup\$

Python 2, 65 55 53 51

s=12345678
while s:r='%-8d'%s;print r+r[::-1];s/=10

Shortened using some of ugoren's ideas.

\$\endgroup\$
  • \$\begingroup\$ Heh, I knew there was room for improvement :P \$\endgroup\$ – Nathan Osman May 12 '13 at 7:51
  • 2
    \$\begingroup\$ You can save a lot by s=s[1:] per loop and while s: \$\endgroup\$ – ugoren May 12 '13 at 8:39
11
\$\begingroup\$

GolfScript (25 chars)

8,{.~10,<1>\' '*.2$-1%n}/
\$\endgroup\$
9
\$\begingroup\$

APL (18)

k,⌽k←↑↑∘(1↓⎕D)¨⌽⍳8

Explanation:

  • 1↓⎕D: the string of digits ("0123456789") minus its first element
  • ↑∘(1↓⎕D)¨⌽⍳8: select the first [8..1] characters ('12345678', '1234567'...)
  • : format as matrix (filling the unused characters with blanks)
  • k,⌽k←: store in k, and display k followed by the vertical mirroring of k
\$\endgroup\$
4
\$\begingroup\$

Ruby: 61 50 characters

s="87654321";s.chars{|c|puts s.reverse+s;s[c]=" "}

Sample run:

bash-4.2$ ruby -e 's="87654321";s.chars{|c|puts s.reverse+s;s[c]=" "}'
1234567887654321
1234567  7654321
123456    654321
12345      54321
1234        4321
123          321
12            21
1              1
\$\endgroup\$
4
\$\begingroup\$

Befunge - 3 x 18 = 54

I felt I had to do something with befunge, it's been too long since I last used it. This problem felt the most appropriate for the language.

It is horrendously slow due to the print loop that takes about 8 actions per character (counting styles differ).

80v >#v"12345678"<
>5 *^ >,#$:_$:1-:v
^2< 0p0+7\*48\_@#<
\$\endgroup\$
4
\$\begingroup\$

JavaScript, 71

s='1234567887654321',i=10;while(--i)console.log(s=s.split(i).join(' '))
\$\endgroup\$
  • \$\begingroup\$ s="1234567887654321";for(i=10;--i;)console.log(s=s.split(i).join(" ")) for 70 characters, @SteveWorley \$\endgroup\$ – WallyWest Oct 27 '14 at 0:02
3
\$\begingroup\$

C, 83 chars

main(a,b,n){
    for(a=12345678,n=1e8,b=n-a-1;a;a/=10)
        printf("%-8d%8d\n",a,b),
        b%=n/=10;
}
\$\endgroup\$
3
\$\begingroup\$

Python 2, 75 62

It won't beat Volatility's answer, but here's another approach using python's mutable strings (bytearray):

s=bytearray('1234567887654321')
for i in range(8):s[8-i:8+i]=i*'  ';print s

Edit

I found a shorter version, using str.replace:

s='1234567887654321'
for c in s[8:]:print s;s=s.replace(c,' ')
\$\endgroup\$
3
\$\begingroup\$

Perl, 41

plus -E switch. Total characters on the command line: 50

requires at least perl5, version 10.

perl -E'say@!=1..8-$_,$"x(2*$_),reverse@!for-0..7'
\$\endgroup\$
  • \$\begingroup\$ I would say this is 42, due to the fact that the standard look on -E is a one-byte addition to the program. \$\endgroup\$ – Timtech Oct 26 '14 at 21:25
3
\$\begingroup\$

Mathematica 92 85 67 54 51

Method #1: (54 chars) Makes array using row#, col#, and distance from left-right edge.

Grid@Array[If[#2<9,#2,17-#2]/.x_/;x+#>9:>" "&,{8,16}]

Method #2: (67 chars) Pad ever-shortening ranges.

Print@@@Table[Join[k = PadRight[Range@i, 8, " "], Reverse@k], {i, 8, 1, -1}];

Method #3: (85 chars) Selectively fill each row of an array.

Start with list of 8 space characters. Replace positions 1 and 16 with "1"; replace "2" at positions 2 and 15, etc.

p = 0; q = 16;
Print @@@Reverse@Rest@NestList[ReplacePart[#, {++p -> p, q-- -> p}]&,Array[" "&,q], 8];

Method #4: (86 chars) Selectively empty each row of an array.

p=8;q=9;
Print@@@NestList[ReplacePart[#,{p---> " ",q++-> " "}]&,Join[k=Range@8,Reverse@k],7];

Method #5: Using strings (92 chars)

p=8;s="12345678";
Print[#,StringReverse@#]&/@NestList[StringReplace[#,ToString@p-- ->  " "]&,s,7];
\$\endgroup\$
  • \$\begingroup\$ That new one is slick! I'd +1 again if I could. :-) btw, you can drop the (), and replace #1 with #: Grid@Array[If[#2<9,#2,17-#2]/.x_/;x+#>9:>" "&,{8,16}] \$\endgroup\$ – Mr.Wizard May 13 '13 at 23:38
  • \$\begingroup\$ Thanks for the tips. Yes, Array can sometimes make nice tables without one's having to add iterators. \$\endgroup\$ – DavidC May 14 '13 at 2:17
3
\$\begingroup\$

PHP, 68

(Inspired by HamZa's answer)

for($n=8;$n;$r[]=$n--)echo str_replace($r," ","1234567887654321\n");

Plays on the fact that PHP's str_replace can accept an array for search and a string for replace, it'll replace every item in the array with the given string. After each iteration, the current number is added to the search array, removing it from the next loop.

Example of the code in action: http://ideone.com/9wVr0X

\$\endgroup\$
  • \$\begingroup\$ hehe nice +1 \$\endgroup\$ – HamZa Jun 3 '13 at 13:58
  • \$\begingroup\$ doesn't appear to put the right number of spaces in the middle though \$\endgroup\$ – nathan hayfield Jun 4 '13 at 22:14
  • \$\begingroup\$ @nathanhayfield: How so? First line has 0 spaces, second has 2, then 4, 6, 8, etc. \$\endgroup\$ – Mr. Llama Jun 5 '13 at 16:27
  • \$\begingroup\$ not when i ran it on writecodeonline.com/php \$\endgroup\$ – nathan hayfield Jun 5 '13 at 16:54
  • \$\begingroup\$ That's because the output wasn't wrapped in <pre> tags. When interpreted as html text, the spaces are collapsed and the newlines are ignored, but if you check the source you'll see otherwise. \$\endgroup\$ – Mr. Llama Jun 5 '13 at 17:30
3
\$\begingroup\$

Marbelous 165

@0
08
>0
LN
--
@0
:LN
}0}0}0}0
..SAPSSD0A
{0
:PS
}0
~~09
..//
<<@0
\\>0
&0//
--@1
@020
&0/\&0
@1
:SA
@0
}0
>0!!
--00@1
@0++//
+O/\@1
+O
:SD
}0@0
\\>0\/
--/\+O
@0..+O

Pseudocode:

MB():
    for x in 8..1:
        LN(x)
LN(x):
    SA(x)
    PS(x)
    SD(x)
    print "\n"
PS(x):
    print " "*(8-x)*2
SA(x):
    for n in 1..x:
        print n
SD(x):
    for n in x..1:
        print n
\$\endgroup\$
2
\$\begingroup\$

Python 2.x - 73 65 63 61 chars

c=1;s='87654321'
while c<9:print s[::-1]+s;s=' '*c+s[c:];c+=1
\$\endgroup\$
2
\$\begingroup\$

PHP, 76

for($i=9;$i>1;){$r[]=$i--;echo str_replace($r,' ','1234567887654321')."\r";}
\$\endgroup\$
2
\$\begingroup\$

K, 28

-1_a,'|:'a:8$'{-1_x}\,/$1+!8

.

k)-1_a,'|:'a:8$'{-1_x}\,/$1+!8
"1234567887654321"
"1234567  7654321"
"123456    654321"
"12345      54321"
"1234        4321"
"123          321"
"12            21"
"1              1"

You could generalise it for 36: {-1_a,'|:'a:(#*m)$'m:{-1_x}\,/$1+!x}

k){-1_a,'|:'a:(#*m)$'m:{-1_x}\,/$1+!x} 5
"1234554321"
"1234  4321"
"123    321"
"12      21"
"1        1"
q)k){-1_a,'|:'a:(#*m)$'m:{-1_x}\,/$1+!x} 15
"123456789101112131415514131211101987654321"
"12345678910111213141  14131211101987654321"
"1234567891011121314    4131211101987654321"
"123456789101112131      131211101987654321"
"12345678910111213        31211101987654321"
"1234567891011121          1211101987654321"
"123456789101112            211101987654321"
"12345678910111              11101987654321"
"1234567891011                1101987654321"
"123456789101                  101987654321"
"12345678910                    01987654321"
"1234567891                      1987654321"
"123456789                        987654321"
"12345678                          87654321"
"1234567                            7654321"
"123456                              654321"
"12345                                54321"
"1234                                  4321"
"123                                    321"
"12                                      21"
"1                                        1"
\$\endgroup\$
2
\$\begingroup\$

Javascript, 67 chars

Insipired by steveworley's answer (I would comment if I could):

Code snippet

a='1234567887654321\n',b='',c=10;while(--c)b+=a=a.split(c).join(' ')
<a href="#" onclick="javascript:document.getElementById('output').innerHTML = b;">Display</a>
<pre id="output">...</pre>

The presence of the last newline does follow the rules.

update: cut 2 chars by removing parentheses (operator precedence) and 1 by removing an unneeded space

It seemed like it's trolling me, because no matter how many different ways I tried to shorten or simplify by un-hardcoding a segment of code, the length stayed the same until I let the "I think this counts" rule written below apply.

(If printing counts as what comes back when this is executed in the chrome console)

\$\endgroup\$
  • \$\begingroup\$ It doesn't look like the other answer, the numbers are not aligned on the right column. \$\endgroup\$ – A.L Oct 26 '14 at 1:51
  • \$\begingroup\$ @A.L. The alert isn't necessary if you read what output comes out of the consonle btw. \$\endgroup\$ – Sophiα2329 Oct 26 '14 at 12:35
  • \$\begingroup\$ To align right column, there should be 1 space instead of 2 in join's string argument. With 2 spaces it is correct aligned in chrome-based browser alert. \$\endgroup\$ – Qwertiy Oct 26 '14 at 13:00
  • \$\begingroup\$ I updated your post (the edit should be accepted) to display the result in a snippet without a JS alert, only one space is needed in this case. \$\endgroup\$ – A.L Oct 27 '14 at 16:58
2
\$\begingroup\$

Brainfuck: 542 Bytes

-[----->+<]>--.+.+.+.+.+.+.+..-.-.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.+.+.+[-->+<]>++++..----[->++<]>-.-.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.+.[-->+<]>+++++....-----[->++<]>.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.--[--->++<]>--......-----[->++<]>-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.-[--->++<]>--........++[-->+++<]>+.-.-.-.>++++++++++.[->+++++
<]>-.+.+.[--->++<]>--..........++[-->+++<]>.-.-.>++++++++++.[->+++++
<]>-.+.--[--->++<]>............[-->+++<]>++.-.>++++++++++.[->+++++
<]>-.-[--->++<]>..............[-->+++<]>+.
\$\endgroup\$
1
\$\begingroup\$

Mathematica, 59

61 using my own ideas:

Grid[Clip[#~Join~Reverse@#&@Range@8,{1,9-#},{," "}]&~Array~8]

Or 59, borrowing from David's answer:

Grid@Array[Join[k=PadRight[Range[9-#],8," "],Reverse@k]&,8]
\$\endgroup\$
  • \$\begingroup\$ I just saved 4 chars by using Grid, inspired by your entry. \$\endgroup\$ – DavidC May 13 '13 at 23:26
1
\$\begingroup\$

R: 52

for(i in 8:1)cat(1:i,rep(" ",16-2*i),i:1,"\n",sep="")
\$\endgroup\$
1
\$\begingroup\$

Haskell, 84

A starting point for someone to improve:

mapM_ putStrLn[let l=take(8-i)"12345678"++replicate i ' 'in l++reverse l|i<-[0..7]]

Most likely part would be to make the l++reverse l point free, letting us get rid of the let-statement, but I'll I could find was ap, which requires imports.

\$\endgroup\$
1
\$\begingroup\$

PostScript: 105 characters

String handling is not easy in PS but can make for relatively simple code:

0 1 7{(1234567887654321)dup
8 3 index sub(              )0 6 -1 roll 2 mul getinterval putinterval =}for

A slightly longer version at 120 chars but can generate different number arches by replacing the 8 at the start of the second line with any number in the range 1 to 9:

/D{dup}def/R{repeat}def/P{=print}def
8 D -1 1{1 1 index{D P 1 add}R pop 2 copy sub{(  )P}R D{D P 1 sub}R pop()=}for pop
\$\endgroup\$
  • \$\begingroup\$ Its nice to see that I'm not the only one who loves PostScript out there. \$\endgroup\$ – AJMansfield Jul 12 '13 at 12:59
1
\$\begingroup\$

GoRuby 2.1

36 chars

8.w(1){|x|a=[*1..x].j.lj 8;s a+a.rv}

Ungolfed

8.downto(1) do |x|
  a = [*1..x].join.ljust(8)
  puts a + a.reverse
end
\$\endgroup\$
1
\$\begingroup\$

K 20

{x,'|:'x:|x$,\$1+!x}    

q)k){x,'|:'x:|x$,\$1+!x}8    
"1234567887654321"    
"1234567  7654321"    
"123456    654321"    
"12345      54321"    
"1234        4321"      
"123          321"    
"12            21"    
"1              1"    
\$\endgroup\$
1
\$\begingroup\$

TSQL, 148

Edit: down to 148 with manatwork's suggestion and tweak to ORDER BY.

Readable:

WITH t AS(
    SELECT 1n, CAST(1 AS VARCHAR(MAX)) o
 UNION ALL
    SELECT n+1,o+CHAR(n+49)
    FROM t
    WHERE n<8
)
SELECT o  + SPACE(16-2*n) + REVERSE(o)
FROM t
ORDER BY 1 DESC

Golfed:

WITH t AS(SELECT 1n,CAST(1AS VARCHAR(MAX))o UNION ALL SELECT 1+n,o+CHAR(n+49)FROM t WHERE n<8)SELECT o+SPACE(16-2*n)+REVERSE(o)FROM t ORDER BY 1DESC

Output:

1234567887654321
1234567  7654321
123456    654321
12345      54321
1234        4321
123          321
12            21
1              1
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice one. But could you please post it also in the format in which you counted 153 characters? Anyway, you can spare 2 characters by using numeric 1 instead of string '1' where you immediately cast it into varchar. This gives me 149 characters: with t as(select 1n,cast(1as varchar(max))o union all select n+1,o+char(n+49)from t where n<8)select o+space(16-2*n)+reverse(o)from t order by o desc. \$\endgroup\$ – manatwork Jun 7 '13 at 9:15
  • \$\begingroup\$ @manatwork: I couldn't reproduce the 153 number, because I kept getting lower. Applied your suggestion, though. Thanks! \$\endgroup\$ – comfortablydrei Jun 10 '13 at 23:01
1
\$\begingroup\$

Haskell, 79

r n x|x>n=' '|True=x
t="87654321"
main=mapM(putStrLn.(`map`("12345678"++t)).r)t

This works by replacing characters > n with ' ', where characters n are sourced from "87654321" (which happens to be the tail of the string to perform substitution on).

\$\endgroup\$
1
\$\begingroup\$

PHP: 61 chars (or 60 chars if you replace the \n by a real ASCII newline)

(Inspired by GigaWatt's and HamZa's answer)

for($n=9;$n;$r[$n--]=" ")echo strtr("1234567887654321\n",$r);

http://ideone.com/FV1NXu

\$\endgroup\$
1
\$\begingroup\$

PowerShell: 38

Golfed code

8..1|%{-join(1..$_+"  "*(8-$_)+$_..1)}

Walkthrough

8..1|%{...} pipe integers from 8 to 1 into a ForEach-Object loop.
-join(...) joins output of the nested code into a single string with no delimiters.
1..$_ outputs integers ascending from 1 to the current integer in the loop.
+" "*(8-$_) adds a double-space, multiplied by the difference between 8 and the current integer, to the output.
+$_..1 adds integers, descending from the current integer to 1, to the output.

\$\endgroup\$
1
\$\begingroup\$

Javascript with lambdas, 147

(s="12345678")[r="replace"](/./g,i=>s[r](RegExp(".{"+(i-1)+"}$"),Array(i*2-1).join(" ")))[r](/\d{1,8} */g,m=>m+(Array(m%10+1).join(m%10+1)-m)+"\n")

Can be checked in Firefox.

\$\endgroup\$
1
\$\begingroup\$

CJam, 22 characters

Not a valid answer (as language was developed after the question), and not the shortest either, but here goes:

8,{S*_,9-~,:)\_2$W%N}%

Try it online here

\$\endgroup\$
0
\$\begingroup\$

Lua, 62

s='1234567887654321'for i=8,1,-1 do print(s)s=s:gsub(i,' ')end
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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