Imprimir um arco de números ascendentes / descendentes


28

Imaginei que um "arco" era a melhor maneira de descrever esse padrão de números:

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

Definido formalmente, cada linha consiste nos números de 1 a 9-n, (n-1)*2espaços e números de 9-n1 (onde nestá a linha atual).

Sua tarefa é escrever, usando o código mais curto possível, um pequeno script / programa que imprima o padrão acima, sujeito às seguintes restrições:

  1. Você não pode codificar o padrão inteiro. Você pode codificar apenas uma única linha do padrão, no máximo.
  2. Seu programa deve imprimir uma nova linha (qualquer combinação de \nou \r) no final de cada linha.

Pronto ... pronto .... vai!


1
Truque pouco adicional estaria disponível com a linha superior 123456787654321, uma vez que equivale a 11111111^2 ;-)
Egor Skriptunoff

3
@EgorSkriptunoff 11111111^2 == 123465787654321 != 1234567887654321(aviso a repetida 8)
Bob

Esta é uma espécie-do inverso Imprimir este diamante
Peter Taylor

6
Parece mais uma cortina .
Volatilidade 15/05

Respostas:


22

Python 2, 65 55 53 51

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

Encurtado usando algumas das idéias de ugoren .


Heh, eu sabia que não havia espaço para melhorias: P
Nathan Osman

2
Você pode economizar muito, s=s[1:]por loop ewhile s:
ugoren


9

APL (18)

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

Explicação:

  • 1↓⎕D: a sequência de dígitos ("0123456789") menos seu primeiro elemento
  • ↑∘(1↓⎕D)¨⌽⍳8: selecione os primeiros [8..1] caracteres ('12345678', '1234567' ...)
  • : formato como matriz (preenchendo os caracteres não utilizados com espaços em branco)
  • k,⌽k←: armazenar ke exibir, kseguido pelo espelhamento vertical dek

4

Ruby: 61 50 caracteres

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

Exemplo de execução:

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

Eu senti que tinha que fazer algo com befunge, faz muito tempo desde a última vez que o usei. Esse problema foi o mais apropriado para o idioma.

É terrivelmente lento devido ao loop de impressão que leva cerca de 8 ações por caractere (os estilos de contagem são diferentes).

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(" "))para 70 caracteres, @SteveWorley
WallyWest

3

C, 83 caracteres

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

Não vai superar a resposta do Volatility, mas aqui está outra abordagem usando as seqüências mutáveis ​​do python ( bytearray):

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

Editar

Encontrei uma versão mais curta, usando str.replace:

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

3

Perl, 41

-Einterruptor de mais . Total de caracteres na linha de comando: 50

requer pelo menos perl5, versão 10.

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

Eu diria que isso é 42, devido ao fato de que a aparência padrão -Eé uma adição de um byte ao programa.
Timtech 26/10

3

Mathematica 92 85 67 54 51

Método 1 : (54 caracteres) Cria um array usando o número da linha, o número da coluna e a distância da borda esquerda-direita.

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

Método # 2 : (67 caracteres) Preencher intervalos de encurtamento sempre.

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

Método 3 : (85 caracteres) Preencher seletivamente cada linha de uma matriz.

Comece com uma lista de 8 caracteres de espaço. Substitua as posições 1 e 16 por "1"; substitua "2" nas posições 2 e 15, etc.

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

Método 4 : (86 caracteres) Esvazie seletivamente cada linha de uma matriz.

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

Método # 5 : Usando strings (92 caracteres)

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

Esse novo é liso! Eu faria +1 novamente se pudesse. :-) btw, você pode soltar o ()e substituir #1por #:Grid@Array[If[#2<9,#2,17-#2]/.x_/;x+#>9:>" "&,{8,16}]
Mr.Wizard

Obrigado pelas dicas. Sim, Arrayàs vezes pode criar boas tabelas sem a necessidade de adicionar iteradores.
DavidC 14/05

3

PHP, 68

(Inspirado pela resposta de HamZa)

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

Diz que o str_replace do PHP pode aceitar uma matriz para pesquisa e uma string para substituir, substituirá todos os itens da matriz pela string especificada. Após cada iteração, o número atual é adicionado à matriz de pesquisa, removendo-o do próximo loop.

Exemplo do código em ação: http://ideone.com/9wVr0X


hehe nice +1
HamZa

não parece colocar o número certo de espaços no meio embora
Nathan campo de feno

@nathanhayfield: Como assim? A primeira linha tem 0 espaços, a segunda tem 2, depois 4, 6, 8, etc.
Mr. Llama

não quando eu corri-lo em writecodeonline.com/php
Nathan hayfield

Isso ocorre porque a saída não foi agrupada em <pre>tags. Quando interpretados como texto html, os espaços são recolhidos e as novas linhas são ignoradas, mas se você verificar a fonte, verá o contrário.
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

Pseudo-código:

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 caracteres

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"

Você pode generalizá-lo por 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 caracteres

Insipired pela resposta de steveworley (eu gostaria de comentar se eu pudesse):

Fragmento de código

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>

A presença da última nova linha segue as regras.

update: recorte 2 caracteres removendo parênteses (precedência do operador) e 1 removendo um espaço desnecessário

Parecia que estava me controlando, porque, independentemente de quantas maneiras diferentes eu tentasse reduzir ou simplificar ao codificar um segmento de código, o comprimento permaneceu o mesmo até que eu aplicasse a regra "Eu acho que isso conta" escrita abaixo.

(Se a impressão contar como o que ocorre quando isso é executado no console do chrome)


Não parece a outra resposta, os números não estão alinhados na coluna da direita.
AL

@AL O alerta não é necessário se você ler qual saída sai do consonle btw.
Sophiα2329

Para alinhar a coluna da direita, deve haver 1 espaço em vez de 2 no argumento de string da junção. Com 2 espaços, é correto alinhado no alerta do navegador baseado em cromo.
Qwertiy

Atualizei sua postagem (a edição deve ser aceita) para exibir o resultado em um trecho sem um alerta JS, apenas um espaço é necessário nesse caso.
AL

2

Brainfuck: 542 bytes

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

1

Mathematica , 59

61 usando minhas próprias idéias:

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

Ou 59, emprestando da resposta de David:

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

Acabei de salvar 4 caracteres usando o Grid, inspirado na sua entrada.
DavidC

1

R: 52

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

1

Haskell, 84

Um ponto de partida para alguém melhorar:

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

A parte mais provável seria l++reverse ldeixar letclaro o ponto, deixando-nos livrar da declaração, mas eu pude descobrir que era ap, o que requer importações.


1

PostScript: 105 caracteres

O manuseio de strings não é fácil no PS, mas pode ser um código relativamente simples:

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

Uma versão um pouco mais longa com 120 caracteres, mas pode gerar arcos numéricos diferentes, substituindo o 8 no início da segunda linha por qualquer número no intervalo de 1 a 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

É bom ver que eu não sou o único que ama PostScript por aí.
AJMansfield

1

GoRuby 2.1

36 caracteres

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

Editar: até 148 com a sugestão de manatwork e ajustar para ORDER BY.

Legível:

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

Golfe:

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

Saída:

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

1
Agradável. Mas você poderia publicá-lo também no formato em que contava 153 caracteres? De qualquer forma, você pode poupar 2 caracteres usando numérico em 1vez de sequência de caracteres em '1'que você o castcoloca imediatamente varchar. Isso me dá 149 caracteres: 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: Não consegui reproduzir o número 153, porque continuava diminuindo. Aplicou sua sugestão, no entanto. Obrigado!
comfortablydrei

1

Haskell, 79

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

Isso funciona substituindo os caracteres> n por ' ', onde os caracteres n são originários de "87654321" (que por acaso é a cauda da string para a substituição).


1

PHP: 61 caracteres (ou 60 caracteres se você substituir o \ n por uma nova linha ASCII real)

(Inspirado nas respostas de GigaWatt e HamZa)

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

http://ideone.com/FV1NXu


1

PowerShell: 38

Código de golfe

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

Passo a passo

8..1|%{... }integra de 8 a 1 em um loop ForEach-Object.
-join(... )une a saída do código aninhado em uma única sequência sem delimitadores.
1..$_gera números inteiros ascendentes de 1 ao número inteiro atual no loop.
+" "*(8-$_)adiciona um espaço duplo, multiplicado pela diferença entre 8 e o número inteiro atual, à saída.
+$_..1adiciona números inteiros, descendentes do número inteiro atual a 1, na saída.


1

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

Pode ser verificado no Firefox.


1

CJam, 22 caracteres

Não é uma resposta válida (como a linguagem foi desenvolvida após a pergunta) e também não é a mais curta, mas aqui vai:

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

Experimente online aqui


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.