Stampa un arco di numeri crescente / decrescente


28

Ho pensato che un "arco" fosse il modo migliore per descrivere questo modello di numeri:

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

Definita formalmente, ogni riga è composta dai numeri da 1 a 9-n, (n-1)*2spazi e numeri 9-nda 1 (dove si ntrova la riga corrente).

Il tuo compito è quello di scrivere, usando il codice più breve possibile, un piccolo script / programma che stampa il modello sopra soggetto alle seguenti restrizioni:

  1. Non è possibile codificare l'intero modello. È possibile codificare al massimo una sola riga del modello al massimo.
  2. Il programma deve stampare una nuova riga (qualsiasi combinazione di \no \r) alla fine di ogni riga.

Pronto ... set .... vai!


1
Sarebbe disponibile un piccolo trucco con la linea superiore 123456787654321uguale a 11111111^2 ;-)
Egor Skriptunoff,

3
@EgorSkriptunoff 11111111^2 == 123465787654321 != 1234567887654321(nota il ripetuto 8)
Bob,

Questo è una specie dell'inverso di Print this diamond
Peter Taylor,

6
Sembra piuttosto un sipario .
Volatilità,

Risposte:


22

Python 2, 65 55 53 51

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

Accorciato usando alcune delle idee di Ugoren .


Heh, sapevo che c'era spazio per miglioramenti: P
Nathan Osman,

2
Puoi risparmiare molto s=s[1:]per ciclo ewhile s:
ugoren


9

APL (18)

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

Spiegazione:

  • 1↓⎕D: la stringa di cifre ("0123456789") meno il suo primo elemento
  • ↑∘(1↓⎕D)¨⌽⍳8: seleziona i primi [8..1] caratteri ('12345678', '1234567' ...)
  • : formatta come matrice (riempiendo i caratteri inutilizzati di spazi)
  • k,⌽k←: archivia ke visualizza kseguito dal mirroring verticale dik

4

Rubino: 61 50 caratteri

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

Esecuzione di esempio:

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

4

Befunge - 3 x 18 = 54

Ho sentito che dovevo fare qualcosa con Befunge, è passato troppo tempo dall'ultima volta che l'ho usato. Questo problema è sembrato il più appropriato per la lingua.

È terribilmente lento a causa del ciclo di stampa che richiede circa 8 azioni per personaggio (gli stili di conteggio differiscono).

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

4

JavaScript, 71

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

s="1234567887654321";for(i=10;--i;)console.log(s=s.split(i).join(" "))per 70 caratteri, @SteveWorley
WallyWest,

3

C, 83 caratteri

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

3

Python 2, 75 62

Non batterà la risposta di Volatility, ma ecco un altro approccio che usa le stringhe mutabili di python ( bytearray):

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

modificare

Ho trovato una versione più breve, usando str.replace:

s='1234567887654321'
for c in s[8:]:print s;s=s.replace(c,' ')

3

Perl, 41

-Einterruttore più . Caratteri totali sulla riga di comando: 50

richiede almeno perl5, versione 10.

perl -E'say@!=1..8-$_,$"x(2*$_),reverse@!for-0..7'

Direi che questo è 42, a causa del fatto che l'aspetto standard -Eè un'aggiunta di un byte al programma.
Timtech,

3

Mathematica 92 85 67 54 51

Metodo # 1 : (54 caratteri) Crea un array usando riga #, colonna # e distanza dal bordo sinistro-destro.

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

Metodo n. 2 : (67 caratteri) Pad intervalli sempre più brevi.

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

Metodo n. 3 : (85 caratteri) Riempi selettivamente ogni riga di un array.

Inizia con un elenco di 8 caratteri spaziali. Sostituire le posizioni 1 e 16 con "1"; sostituire "2" nelle posizioni 2 e 15, ecc.

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

Metodo n. 4 : (86 caratteri) Svuota selettivamente ogni riga di un array.

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

Metodo n. 5 : utilizzo di stringhe (92 caratteri)

p=8;s="12345678";
Print[#,StringReverse@#]&/@NestList[StringReplace[#,ToString@p-- ->  " "]&,s,7];

Quella nuova è liscia! Farei +1 di nuovo se potessi. :-) tra l'altro, puoi rilasciare ()e sostituire #1con #:Grid@Array[If[#2<9,#2,17-#2]/.x_/;x+#>9:>" "&,{8,16}]
Mr.Wizard,

Grazie per i suggerimenti Sì, a Arrayvolte puoi creare dei bei tavoli senza dover aggiungere iteratori.
DavidC

3

PHP, 68

(Ispirato dalla risposta di HamZa)

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

Si basa sul fatto che str_replace di PHP può accettare un array per la ricerca e una stringa per la sostituzione, sostituirà ogni elemento dell'array con la stringa specificata. Dopo ogni iterazione, il numero corrente viene aggiunto all'array di ricerca, rimuovendolo dal ciclo successivo.

Esempio del codice in azione: http://ideone.com/9wVr0X


hehe nice +1
HamZa

non sembra mettere il giusto numero di spazi nel mezzo però
Nathan Hayfield,

@nathanhayfield: in che modo? La prima riga ha 0 spazi, la seconda ha 2, quindi 4, 6, 8, ecc.
Mr. Llama

non quando l'ho eseguito su writecodeonline.com/php
nathan hayfield il

Questo perché l'output non è stato racchiuso tra <pre>tag. Quando interpretati come testo html, gli spazi vengono compressi e le nuove righe vengono ignorate, ma se si controlla l'origine si vedrà diversamente.
Mr. Llama,

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

pseudocodice:

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

2

Python 2.x - 73 65 63 61 caratteri

c=1;s='87654321'
while c<9:print s[::-1]+s;s=' '*c+s[c:];c+=1

2

PHP, 76

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

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"

Puoi generalizzare per 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"

2

Javascript, 67 caratteri

Ispirato dalla risposta di steveworley (vorrei commentare se potessi):

Snippet di codice

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>

La presenza dell'ultima riga segue le regole.

aggiornamento: taglia 2 caratteri rimuovendo le parentesi (precedenza dell'operatore) e 1 rimuovendo uno spazio non necessario

Sembra che mi stia trollando, perché non importa quanti modi diversi ho cercato di abbreviare o semplificare annullando la codifica di un segmento di codice, la lunghezza è rimasta invariata fino a quando non ho lasciato applicare la regola "Penso che conta" scritta di seguito.

(Se la stampa conta come ciò che ritorna quando questo viene eseguito nella console di Chrome)


Non sembra l'altra risposta, i numeri non sono allineati nella colonna di destra.
AL

@AL L'avviso non è necessario se leggi quale output esce dal consonle btw.
Sophiα2329,

Per allineare la colonna di destra, dovrebbe esserci 1 spazio anziché 2 nell'argomento stringa del join. Con 2 spazi è allineato correttamente nell'avviso del browser basato su Chrome.
Qwertiy,

Ho aggiornato il tuo post (la modifica deve essere accettata) per visualizzare il risultato in uno snippet senza un avviso JS, in questo caso è necessario solo uno spazio.
AL

2

Brainfuck: 542 byte

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

1

Mathematica , 59

61 usando le mie idee:

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

O 59, prendendo in prestito dalla risposta di David:

Grid@Array[Join[k=PadRight[Range[9-#],8," "],Reverse@k]&,8]

Ho appena salvato 4 caratteri usando Grid, ispirato alla tua voce.
DavidC

1

R: 52

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

1

Haskell, 84

Un punto di partenza per qualcuno da migliorare:

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

La parte più probabile sarebbe quella di rendere il l++reverse lpunto libero, permettendoci di sbarazzarci della letdichiarazione, ma vedrò che era necessario ap, che richiede importazioni.


1

PostScript: 105 caratteri

La gestione delle stringhe non è facile in PS ma può rendere il codice relativamente semplice:

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

Una versione leggermente più lunga a 120 caratteri, ma può generare diversi archi numerici sostituendo l'8 all'inizio della seconda riga con qualsiasi numero compreso tra 1 e 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

È bello vedere che non sono l'unico che adora PostScript.
AJMansfield,

1

GoRuby 2.1

36 caratteri

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

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"    

1

TSQL, 148

Modifica: fino a 148 con il suggerimento di manatwork e modifica su ORDER BY.

Leggibile:

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

Produzione:

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

1
Ben fatto. Ma potresti pubblicarlo anche nel formato in cui hai contato 153 caratteri? Ad ogni modo, puoi risparmiare 2 caratteri usando il valore numerico 1anziché la stringa in '1'cui lo hai immediatamente castinserito varchar. Questo mi dà 149 caratteri: 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.
arte

@manatwork: non sono riuscito a riprodurre il numero 153, perché ho continuato ad abbassarmi. Ho applicato il tuo suggerimento, però. Grazie!
confortevolmente

1

Haskell, 79

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

Funziona sostituendo i caratteri> n con ' ', dove i caratteri n provengono da "87654321" (che risulta essere la coda della stringa su cui eseguire la sostituzione).


1

PHP: 61 caratteri (o 60 caratteri se si sostituisce \ n con una nuova riga ASCII reale)

(Ispirato dalla risposta di GigaWatt e HamZa)

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

http://ideone.com/FV1NXu


1

PowerShell: 38

Codice golf

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

Procedura dettagliata

8..1|%{... }integer pipe da 8 a 1 in un ciclo ForEach-Object.
-join(... )unisce l'output del codice nidificato in una singola stringa senza delimitatori.
1..$_genera numeri interi che salgono da 1 all'intero corrente nel loop.
+" "*(8-$_)aggiunge un doppio spazio, moltiplicato per la differenza tra 8 e l'intero corrente, all'output.
+$_..1aggiunge numeri interi, decrescente dal numero intero corrente a 1, all'output.


1

Javascript con 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")

Può essere controllato in Firefox.


1

CJam, 22 caratteri

Non una risposta valida (dato che il linguaggio è stato sviluppato dopo la domanda), e nemmeno la più breve, ma ecco:

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

Provalo online qui


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.