Wydrukuj łuk rosnących / malejących liczb

28

Uznałem, że „łuk” jest najlepszym sposobem na opisanie tego wzoru liczb:

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

Formalnie zdefiniowany, każdy wiersz składa się z liczb od 1 do 9-n, (n-1)*2spacji i liczb 9-ndo 1 (gdzie njest bieżąca linia).

Twoim zadaniem jest napisanie, używając możliwie najkrótszego kodu, małego skryptu / programu, który drukuje powyższy wzór z zastrzeżeniem następujących ograniczeń:

  1. Nie możesz zakodować całego wzoru na stałe. Możesz zakodować maksymalnie tylko jedną linię wzoru.
  2. Twój program musi wydrukować nowy wiersz (dowolną kombinację \nlub \r) na końcu każdej linii.

Gotowi do startu start!

Nathan Osman
źródło
1
Dodatkowa sztuczka byłaby dostępna z górną linią, 123456787654321ponieważ jest równa 11111111^2 ;-)
Egor Skriptunoff
3
@EgorSkriptunoff 11111111^2 == 123465787654321 != 1234567887654321(zauważ powtórzenie 8)
Bob
To coś w rodzaju odwrotności wydruku tego diamentu
Peter Taylor
6
Wygląda raczej jak zasłona .
Zmienność

Odpowiedzi:

22

Python 2, 65 55 53 51

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

Skrócono przy użyciu niektórych pomysłów ugorena .

Zmienność
źródło
Heh, wiedziałem, że jest miejsce na ulepszenia: P
Nathan Osman
2
Możesz dużo zaoszczędzić s=s[1:]na pętlę iwhile s:
ugoren
11

GolfScript (25 znaków)

8,{.~10,<1>\' '*.2$-1%n}/
Peter Taylor
źródło
9

APL (18)

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

Wyjaśnienie:

  • 1↓⎕D: ciąg cyfr („0123456789”) minus pierwszy element
  • ↑∘(1↓⎕D)¨⌽⍳8: wybierz pierwsze [8..1] znaków („12345678”, „1234567” ...)
  • : formatuj jako macierz (wypełniając nieużywane znaki spacjami)
  • k,⌽k←: zapisz ki wyświetl, ka następnie wykonaj odbicie lustrzane w pioniek
marinus
źródło
4

Rubin: 61 50 znaków

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

Przykładowy przebieg:

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
człowiek w pracy
źródło
4

Befunge - 3 x 18 = 54

Czułem, że muszę coś zrobić z befunge, minęło już dużo czasu, odkąd go ostatnio używałem. Ten problem wydawał się najbardziej odpowiedni dla języka.

Jest strasznie powolny ze względu na pętlę drukowania, która wykonuje około 8 akcji na znak (style liczenia różnią się).

80v >#v"12345678"<
>5 *^ >,#$:_$:1-:v
^2< 0p0+7\*48\_@#<
shiona
źródło
4

JavaScript, 71

s='1234567887654321',i=10;while(--i)console.log(s=s.split(i).join(' '))
Steveworley
źródło
s="1234567887654321";for(i=10;--i;)console.log(s=s.split(i).join(" "))na 70 znaków, @SteveWorley
WallyWest
3

C, 83 znaki

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
źródło
3

Python 2, 75 62

Nie przebije odpowiedzi Volatility, ale oto inne podejście z użyciem zmiennych ciągów Pythona ( bytearray):

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

Edytować

Znalazłem krótszą wersję, używając str.replace:

s='1234567887654321'
for c in s[8:]:print s;s=s.replace(c,' ')
Baptiste M.
źródło
3

Perl, 41

plus -Eprzełącznik. Całkowita liczba znaków w wierszu poleceń: 50

wymaga co najmniej perl5, wersja 10.

perl -E'say@!=1..8-$_,$"x(2*$_),reverse@!for-0..7'
amon
źródło
Powiedziałbym, że to 42, ponieważ standardowy wygląd -Ejest jednobajtowym dodatkiem do programu.
Timtech
3

Mathematica 92 85 67 54 51

Metoda nr 1 : (54 znaki) Tworzy tablicę za pomocą wiersza #, col # i odległości od lewej-prawej krawędzi.

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

Metoda nr 2 : (67 znaków) Pad coraz krótszych zakresów.

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

Metoda nr 3 : (85 znaków) Selektywnie wypełnij każdy wiersz tablicy.

Zacznij od listy 8 znaków spacji. Zamień pozycje 1 i 16 na „1”; wymienić „2” w pozycjach 2 i 15 itd.

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

Metoda nr 4 : (86 znaków) Selektywnie opróżnij każdy wiersz tablicy.

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

Metoda nr 5 : Używanie ciągów znaków (92 znaki)

p=8;s="12345678";
Print[#,StringReverse@#]&/@NestList[StringReplace[#,ToString@p-- ->  " "]&,s,7];
DavidC
źródło
Ten nowy jest elegancki! Dałbym +1, gdybym mógł. :-) BTW, można upuścić ()i wymienić #1z #:Grid@Array[If[#2<9,#2,17-#2]/.x_/;x+#>9:>" "&,{8,16}]
Mr.Wizard
Dzięki za wskazówki. Tak, Arrayczasami można tworzyć fajne stoły bez konieczności dodawania iteratorów.
DavidC
3

PHP, 68

(Zainspirowany odpowiedzią HamZy)

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

Okazuje się, że str_replace PHP może zaakceptować tablicę do wyszukiwania i ciąg znaków do zamiany, to zastąpi każdy element w tablicy danym ciągiem. Po każdej iteracji bieżący numer jest dodawany do tablicy wyszukiwania, usuwając go z następnej pętli.

Przykład kodu w akcji: http://ideone.com/9wVr0X

Pan Llama
źródło
hehe nice +1
HamZa
nie wydaje się jednak umieszczać odpowiedniej liczby spacji na środku
nathan hayfield
@nathanhayfield: Jak to możliwe? Pierwsza linia ma 0 spacji, druga ma 2, a następnie 4, 6, 8 itd.
Pan Llama
nie kiedy uruchomiłem go na writecodeonline.com/php
nathan hayfield,
Jest tak, ponieważ dane wyjściowe nie zostały zawinięte w <pre>znaczniki. Interpretowane jako tekst HTML spacje są zwinięte, a znaki nowej linii są ignorowane, ale jeśli zaznaczysz źródło, zobaczysz inaczej.
Pan Llama,
3

Cudowny 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

Pseudo kod:

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
źródło
2

Python 2.x - 73 65 63 61 znaków

c=1;s='87654321'
while c<9:print s[::-1]+s;s=' '*c+s[c:];c+=1
TerryA
źródło
2

PHP, 76

for($i=9;$i>1;){$r[]=$i--;echo str_replace($r,' ','1234567887654321')."\r";}
HamZa
źródło
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"

Możesz uogólnić na 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"
tartin
źródło
2

JavaScript, 67 znaków

Zainspirowany odpowiedzią Steveworleya (skomentowałbym, gdybym mógł):

Fragment kodu

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>

Obecność ostatniego nowego wiersza jest zgodna z zasadami.

aktualizacja: wytnij 2 znaki usuwając nawiasy (pierwszeństwo operatora) i 1 usuwając niepotrzebne miejsce

Wyglądało na to, że mnie trolluje, ponieważ bez względu na to, ile różnych sposobów starałem się skrócić lub uprościć, odkodowawszy fragment kodu, długość pozostała taka sama, dopóki nie pozwoliłem na zastosowanie poniższej reguły „Myślę, że to się liczy”.

(Jeśli drukowanie liczy się jako to, co powraca, gdy jest wykonywane w konsoli chrome)

Sophiα2329
źródło
Nie wygląda to na inną odpowiedź, liczby nie są wyrównane w prawej kolumnie.
AL
@AL Alert nie jest konieczny, jeśli przeczytasz, jakie dane wyjściowe pochodzą z spółgłosek btw.
Sophiα2329
Aby wyrównać do prawej kolumny, argument argumentu ciągu powinien zawierać 1 spację zamiast 2. Z 2 spacjami jest poprawnie wyrównany w alercie przeglądarki opartym na chrome.
Qwertiy
Zaktualizowałem twój post (edycja powinna zostać zaakceptowana), aby wyświetlić wynik we fragmencie bez alertu JS, w tym przypadku potrzebna jest tylko jedna spacja.
AL
2

Brainfuck: 542 bajtów

-[----->+<]>--.+.+.+.+.+.+.+..-.-.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.+.+.+[-->+<]>++++..----[->++<]>-.-.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.+.[-->+<]>+++++....-----[->++<]>.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.--[--->++<]>--......-----[->++<]>-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.-[--->++<]>--........++[-->+++<]>+.-.-.-.>++++++++++.[->+++++
<]>-.+.+.[--->++<]>--..........++[-->+++<]>.-.-.>++++++++++.[->+++++
<]>-.+.--[--->++<]>............[-->+++<]>++.-.>++++++++++.[->+++++
<]>-.-[--->++<]>..............[-->+++<]>+.
NaCl
źródło
1

Mathematica , 59

61 wykorzystując własne pomysły:

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

Lub 59, zapożyczając z odpowiedzi Dawida:

Grid@Array[Join[k=PadRight[Range[9-#],8," "],Reverse@k]&,8]
Mr.Wizard
źródło
Właśnie zapisałem 4 znaki przy użyciu siatki, zainspirowanej twoim wpisem.
DavidC
1

R: 52

for(i in 8:1)cat(1:i,rep(" ",16-2*i),i:1,"\n",sep="")
flodel
źródło
1

Haskell, 84

Punktem wyjścia dla kogoś do poprawy:

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

Najprawdopodobniej częścią byłoby l++reverse luwolnienie punktu, pozwalając nam pozbyć się tego stwierdzenia let, ale mogę znaleźć ap, że wymaga importu.

shiona
źródło
1

PostScript: 105 znaków

Obsługa ciągów znaków nie jest łatwa w PS, ale może być stosunkowo prostym kodem:

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

Nieco dłuższa wersja ze 120 znakami, ale może generować różne łuki liczbowe, zastępując 8 na początku drugiej linii dowolną liczbą z zakresu od 1 do 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
źródło
Miło jest widzieć, że nie tylko ja kocham PostScript.
AJMansfield
1

GoRuby 2.1

36 znaków

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

Nie golfił

8.downto(1) do |x|
  a = [*1..x].join.ljust(8)
  puts a + a.reverse
end
Patrick Oscity
źródło
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
źródło
1

TSQL, 148

Edycja: do 148 z sugestią manatwork i dostosowanie do ORDER BY.

Czytelny:

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

Gra w golfa:

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

Wydajność:

1234567887654321
1234567  7654321
123456    654321
12345      54321
1234        4321
123          321
12            21
1              1
comfortlydrei
źródło
1
Niezłe. Ale czy mógłbyś zamieścić go również w formacie, w którym policzyłeś 153 znaki? W każdym razie możesz zaoszczędzić 2 znaki, używając numerycznej 1zamiast ciągu znaków w '1'miejscu, w którym je od razu castumieszczasz varchar. To daje mi 149 znaków: 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
@manatwork: Nie mogłem odtworzyć numeru 153, ponieważ ciągle spadałem. Zastosowałem jednak twoją sugestię. Dzięki!
komfortowodrei
1

Haskell, 79

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

Działa to poprzez zamianę znaków> n na, przy ' 'czym znaki n pochodzą z „87654321” (który okazuje się być ogonem ciągu, na którym należy wykonać podstawienie).

Joey Adams
źródło
1

PHP: 61 znaków (lub 60 znaków, jeśli zastąpisz \ n prawdziwą nową linią ASCII)

(Zainspirowany odpowiedzią GigaWatta i HamZy)

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

http://ideone.com/FV1NXu

Bwoebi
źródło
1

PowerShell: 38

Kod do gry w golfa

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

Przewodnik

8..1|%{... }potokuj liczby całkowite od 8 do 1 w pętli ForEach-Object.
-join(... )łączy wynik zagnieżdżonego kodu w jednym ciągu bez separatorów.
1..$_wyprowadza w pętli liczby całkowite od 1 do bieżącej liczby całkowitej.
+" "*(8-$_)dodaje do wyjścia podwójną spację pomnożoną przez różnicę między 8 a bieżącą liczbą całkowitą.
+$_..1dodaje do wyjścia liczby całkowite, malejące od bieżącej liczby całkowitej do 1.

Iszi
źródło
1

JavaScript z 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")

Można to sprawdzić w przeglądarce Firefox.

Qwertiy
źródło
1

CJam, 22 znaki

Niepoprawna odpowiedź (ponieważ język został opracowany po pytaniu) i nie jest najkrótsza, ale oto:

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

Wypróbuj online tutaj

Optymalizator
źródło
0

Lua, 62

s='1234567887654321'for i=8,1,-1 do print(s)s=s:gsub(i,' ')end
Egor Skriptunoff
źródło