Print an arch of ascending / descending numbers

28

2

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!

Nathan Osman

Posted 2013-05-12T05:58:23.600

Reputation: 596

1Additional little trick would be available with upper line 123456787654321 as it equals to 11111111^2 ;-) – Egor Skriptunoff – 2013-05-12T13:57:27.503

3@EgorSkriptunoff 11111111^2 == 123465787654321 != 1234567887654321 (notice the repeated 8) – Bob – 2013-05-12T14:43:02.320

This is sort-of the inverse of Print this diamond

– Peter Taylor – 2013-05-14T09:23:21.063

6

It looks rather like a curtain.

– Volatility – 2013-05-15T08:53:06.783

Answers

22

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.

Volatility

Posted 2013-05-12T05:58:23.600

Reputation: 3 206

Heh, I knew there was room for improvement :P – Nathan Osman – 2013-05-12T07:51:45.993

2You can save a lot by s=s[1:] per loop and while s: – ugoren – 2013-05-12T08:39:38.253

11

GolfScript (25 chars)

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

Peter Taylor

Posted 2013-05-12T05:58:23.600

Reputation: 41 901

9

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

marinus

Posted 2013-05-12T05:58:23.600

Reputation: 30 224

4

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

manatwork

Posted 2013-05-12T05:58:23.600

Reputation: 17 865

4

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\_@#<

shiona

Posted 2013-05-12T05:58:23.600

Reputation: 2 889

4

JavaScript, 71

s='1234567887654321',i=10;while(--i)console.log(s=s.split(i).join(' '))

steveworley

Posted 2013-05-12T05:58:23.600

Reputation: 41

s="1234567887654321";for(i=10;--i;)console.log(s=s.split(i).join(" ")) for 70 characters, @SteveWorley – WallyWest – 2014-10-27T00:02:13.037

3

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;
}

ugoren

Posted 2013-05-12T05:58:23.600

Reputation: 16 527

3

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,' ')

Baptiste M.

Posted 2013-05-12T05:58:23.600

Reputation: 61

3

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];

DavidC

Posted 2013-05-12T05:58:23.600

Reputation: 24 524

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}] – Mr.Wizard – 2013-05-13T23:38:30.383

Thanks for the tips. Yes, Array can sometimes make nice tables without one's having to add iterators. – DavidC – 2013-05-14T02:17:29.783

3

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'

amon

Posted 2013-05-12T05:58:23.600

Reputation: 309

I would say this is 42, due to the fact that the standard look on -E is a one-byte addition to the program. – Timtech – 2014-10-26T21:25:56.703

3

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

Mr. Llama

Posted 2013-05-12T05:58:23.600

Reputation: 2 387

hehe nice +1 – HamZa – 2013-06-03T13:58:36.527

doesn't appear to put the right number of spaces in the middle though – nathan hayfield – 2013-06-04T22:14:52.273

@nathanhayfield: How so? First line has 0 spaces, second has 2, then 4, 6, 8, etc. – Mr. Llama – 2013-06-05T16:27:24.653

not when i ran it on http://writecodeonline.com/php/

– nathan hayfield – 2013-06-05T16:54:46.997

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. – Mr. Llama – 2013-06-05T17:30:21.120

3

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

Sparr

Posted 2013-05-12T05:58:23.600

Reputation: 5 758

2

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

TerryA

Posted 2013-05-12T05:58:23.600

Reputation: 171

2

PHP, 76

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

HamZa

Posted 2013-05-12T05:58:23.600

Reputation: 161

2

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"

tmartin

Posted 2013-05-12T05:58:23.600

Reputation: 3 917

2

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)

Sophiα2329

Posted 2013-05-12T05:58:23.600

Reputation: 121

It doesn't look like the other answer, the numbers are not aligned on the right column. – A.L – 2014-10-26T01:51:23.913

@A.L. The alert isn't necessary if you read what output comes out of the consonle btw. – Sophiα2329 – 2014-10-26T12:35:19.577

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. – Qwertiy – 2014-10-26T13:00:22.243

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. – A.L – 2014-10-27T16:58:30.870

2

Brainfuck: 542 Bytes

-[----->+<]>--.+.+.+.+.+.+.+..-.-.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.+.+.+[-->+<]>++++..----[->++<]>-.-.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.+.[-->+<]>+++++....-----[->++<]>.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.--[--->++<]>--......-----[->++<]>-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.-[--->++<]>--........++[-->+++<]>+.-.-.-.>++++++++++.[->+++++
<]>-.+.+.[--->++<]>--..........++[-->+++<]>.-.-.>++++++++++.[->+++++
<]>-.+.--[--->++<]>............[-->+++<]>++.-.>++++++++++.[->+++++
<]>-.-[--->++<]>..............[-->+++<]>+.

NaCl

Posted 2013-05-12T05:58:23.600

Reputation: 528

1

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.

shiona

Posted 2013-05-12T05:58:23.600

Reputation: 2 889

1

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]

Mr.Wizard

Posted 2013-05-12T05:58:23.600

Reputation: 2 481

I just saved 4 chars by using Grid, inspired by your entry. – DavidC – 2013-05-13T23:26:32.270

1

R: 52

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

flodel

Posted 2013-05-12T05:58:23.600

Reputation: 2 345

1

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

MrMRDubya

Posted 2013-05-12T05:58:23.600

Reputation: 171

Its nice to see that I'm not the only one who loves PostScript out there. – AJMansfield – 2013-07-12T12:59:19.457

1

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

Patrick Oscity

Posted 2013-05-12T05:58:23.600

Reputation: 765

1

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"    

ppp

Posted 2013-05-12T05:58:23.600

Reputation: 11

1

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

comfortablydrei

Posted 2013-05-12T05:58:23.600

Reputation: 701

1Nice 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. – manatwork – 2013-06-07T09:15:02.077

@manatwork: I couldn't reproduce the 153 number, because I kept getting lower. Applied your suggestion, though. Thanks! – comfortablydrei – 2013-06-10T23:01:06.460

1

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).

Joey Adams

Posted 2013-05-12T05:58:23.600

Reputation: 9 929

1

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

bwoebi

Posted 2013-05-12T05:58:23.600

Reputation: 1 721

1

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.

Iszi

Posted 2013-05-12T05:58:23.600

Reputation: 2 369

1

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.

Qwertiy

Posted 2013-05-12T05:58:23.600

Reputation: 2 697

1

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

Optimizer

Posted 2013-05-12T05:58:23.600

Reputation: 25 836

0

Lua, 62

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

Egor Skriptunoff

Posted 2013-05-12T05:58:23.600

Reputation: 688

0

Tcl: 91 characters

set i 10
set n 1234567887654321
while {[incr i -1]} {puts [set n [string map "$i { }" $n]]}

wolfhammer

Posted 2013-05-12T05:58:23.600

Reputation: 1 219

0

K 27

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

rrr

Posted 2013-05-12T05:58:23.600

Reputation: 31

0

J: 34 31 characters

(,.|."1)|.(>:i.8){."0 1(49}.a.)

Been a while since I've coded in J. I'm sure I can shave off some characters somewhere.

SL2

Posted 2013-05-12T05:58:23.600

Reputation: 171

0

k, 33 chars

{|:{x,'|:'x}a$,/'$:{1+'!x}'1+!a:x}9

Manish Anand

Posted 2013-05-12T05:58:23.600

Reputation: 1

0

Jelly, 11 bytes, non-competing (I think?)

RURz⁶Zm0$€Y

Try it online!

RURz⁶Zm0$€Y  Main Link
RU           Inverse Range
  R          Range ([1...x], [1..x-1], [1..x-2], ..., [1])
   z⁶Z       Zips, filling by spaces, and then zips back (pads)
         €   Map...
      m0$    ...appending the reverse of each element to itself
          Y  Newline-delimited

HyperNeutrino

Posted 2013-05-12T05:58:23.600

Reputation: 26 575

0

Java, 127

void a(){for(int y=0;y<8;System.out.println(y++==9?"":""))for(int c=0,x=1;c<16;System.out.print(y+(x=++c<=8?c:8-c+9)>8?"":x));}

Loovjo

Posted 2013-05-12T05:58:23.600

Reputation: 7 357