Parte inferior da ampulheta

14

Desafio:

Entrada: Três números inteiros: comprimento da borda inferior; quantidade inicial de grãos de areia; índice

Saída: gera o estado da parte inferior de uma ampulheta no índice especificado, com base no comprimento da borda inferior e na quantidade de grãos de areia.

Regras do desafio:

  • Simulamos os grãos de areia com os dígitos 1-9
  • Colocamos a quantidade restante de grãos de areia no topo no meio, seguida por um único caractere de sua própria escolha (excluindo dígitos, espaços em branco e novas linhas; ou seja -) na linha abaixo
  • Quando a ampulheta está sendo preenchida, a preenchemos por linha, um dígito de cada vez
  • Quando a areia pode ir para a esquerda ou para a direita, SEMPRE vamos para a direita (o mesmo se aplica ao equilíbrio da quantidade restante de grãos de areia acima da ampulheta)
  • Quando chegamos às 9, está cheio e não podemos mais colocar areia nesse local específico na ampulheta
  • A quantidade de grãos de areia restantes também está sempre alinhada corretamente
  • Uma vez que a metade inferior da ampulheta esteja completamente cheia, ou a quantidade de grãos de areia deixada chegue a 0, não podemos mais avançar, e essa seria a saída para todos os índices além deste ponto
  • Os índices 0 ou 1 são permitidos e especifique o que você usou em sua resposta.
  • Espaços à direita e à esquerda e uma nova linha à direita ou à esquerda são opcionais
  • Você pode usar qualquer outro caractere em vez de zero para preencher os espaços vazios da parte inferior da ampulheta (excluindo dígitos, novas linhas ou o caractere que você usou como pescoço), se você optar por exibi-los.
  • O comprimento da borda inferior sempre será ímpar
  • O comprimento da borda inferior será >= 3; e as quantidades de grãos de areia>= 0
  • Se você quiser, também poderá imprimir todos os estados, inclusive o índice fornecido
  • Você pode assumir que o índice (indexado 0) nunca será maior que a quantidade total de grãos de areia (portanto, quando houver 100 grãos de areia, o índice 100 será a entrada de índice válida máxima).
  • O primeiro índice (0 para indexado em 0; 1 para indexado em 1) produzirá uma ampulheta vazia com a quantidade de grãos de areia acima dela.

Exemplo: As imagens (ou ascii-art) dizem mais de mil palavras, então aqui está um exemplo:

Comprimento da extremidade inferior da entrada: 5
Quantidade de grãos de areia de entrada: em 100
vez de um índice atual, eu mostro todas as etapas aqui:

Saída para todos os índices possíveis com comprimento na extremidade inferior 5e quantidade de grãos de areia100 :

 100
  -
  0
 000
00000

  99
  -
  0
 000
00100

  98
  -
  0
 000
00110

  97
  -
  0
 000
01110

  96
  -
  0
 000
01111

  95
  -
  0
 000
11111

  94
  -
  0
 000
11211

  93
  -
  0
 000
11221

  92
  -
  0
 000
12221

  91
  -
  0
 000
12222

  90
  -
  0
 000
22222

  89
  -
  0
 000
22322

  88
  -
  0
 000
22332

  87
  -
  0
 000
23332

  86
  -
  0
 000
23333

  85
  -
  0
 000
33333

  84
  -
  0
 000
33433

  83
  -
  0
 000
33443

  82
  -
  0
 000
34443

  81
  -
  0
 000
34444

  80
  -
  0
 000
44444

  79
  -
  0
 000
44544

  78
  -
  0
 000
44554

  77
  -
  0
 000
45554

  76
  -
  0
 000
45555

  75
  -
  0
 000
55555

  74
  -
  0
 000
55655

  73
  -
  0
 000
55665

  72
  -
  0
 000
56665

  71
  -
  0
 000
56666

  70
  -
  0
 000
66666

  69
  -
  0
 000
66766

  68
  -
  0
 000
66776

  67
  -
  0
 000
67776

  66
  -
  0
 000
67777

  65
  -
  0
 000
77777

  64
  -
  0
 000
77877

  63
  -
  0
 000
77887

  62
  -
  0
 000
78887

  61
  -
  0
 000
78888

  60
  -
  0
 000
88888

  59
  -
  0
 000
88988

  58
  -
  0
 000
88998

  57
  -
  0
 000
89998

  56
  -
  0
 000
89999

  55
  -
  0
 000
99999

  54
  -
  0
 010
99999

  53
  -
  0
 011
99999

  52
  -
  0
 111
99999

  51
  -
  0
 121
99999

  50
  -
  0
 122
99999

  49
  0
 222
99999

  48
  -
  0
 232
99999

  47
  -
  0
 233
99999

  46
  -
  0
 333
99999

  45
  -
  0
 343
99999

  44
  -
  0
 344
99999

  43
  -
  0
 444
99999

  42
  -
  0
 454
99999

  41
  -
  0
 455
99999

  40
  -
  0
 555
99999

  39
  -
  0
 565
99999

  38
  -
  0
 566
99999

  37
  -
  0
 666
99999

  36
  -
  0
 676
99999

  35
  -
  0
 677
99999

  34
  -
  0
 777
99999

  33
  -
  0
 787
99999

  32
  -
  0
 788
99999

  31
  -
  0
 888
99999

  30
  -
  0
 898
99999

  29
  -
  0
 899
99999

  28
  -
  0
 999
99999

  27
  -
  1
 999
99999

  26
  -
  2
 999
99999

  25
  -
  3
 999
99999

  24
  -
  4
 999
99999

  23
  -
  5
 999
99999

  22
  -
  6
 999
99999

  21
  -
  7
 999
99999

  20
  -
  8
 999
99999

  19
  -
  9
 999
99999

Então, como exemplo:

inputs: 5,100,1
output:
  99
  -
  0
 000
00100

Same example with another valid output format:
  99
  ~
  . 
 ...
..1..

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • Aplicam-se regras padrão à sua resposta, para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados, programas completos. Sua chamada.
  • Lacunas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código.
  • Além disso, adicione uma explicação, se necessário.

Casos de teste:

INPUTS: bottom-edge length, amount of grains of sand, index (0-indexed)

inputs: 5,100,1
output:
  99
  -
  0
 000
00100

inputs: 5,100,24
output:
  76
  -
  0
 000
45555

inputs: 5,100,100
output:
  19
  -
  9
 999
99999

inputs: 5,10,15
output:
  0
  -
  0
 000
22222

inputs: 3,30,20
output:
 10
 -
 0
677

inputs: 3,3,0
 3
 -
 0
000

inputs: 9,250,100
   150
    -
    0
   000
  00000
 2333332
999999999

inputs: 9,225,220
    5
    -
    4
   999
  99999
 9999999
999999999

inputs: 13,1234567890,250
  1234567640
      -
      0
     000
    00000
   0000000
  344444443
 99999999999
9999999999999

inputs: 25,25,25
             0
             -
             0
            000
           00000
          0000000
         000000000
        00000000000
       0000000000000
      000000000000000
     00000000000000000
    0000000000000000000
   000000000000000000000
  00000000000000000000000
 1111111111111111111111111
Kevin Cruijssen
fonte
1
Por 5,100,10000que faz 20+9+9+9+9+9+9+9+9+9 = 101?
Neil
@ Neil Vou mudar um pouco as regras para que o índice nunca ultrapasse a soma total. Provavelmente melhor para entender.
Kevin Cruijssen 25/01
3
Relacionados
Laikoni
a primeira entrada é sempre um número ímpar?
Brian H.
@BrianH. " O comprimento da borda inferior será sempre estranho ". Sei que tenho regras demais neste desafio, para que eu possa entender que você já o leu. :)
Kevin Cruijssen

Respostas:

3

05AB1E , 68 63 59 57 56 bytes

IÅÉÅ9[DOO²Q#ćD_Piˆëć<¸«¸ì]ćā<ΣÉ}2äćR¸ì˜è¸ì¯ìJDSOIα'-‚ì.C

Experimente online!

Explicação

IÅÉÅ9
Inicializamos a pilha com uma lista de 9.
Cada lista representa uma linha, portanto, o comprimento de cada lista é ímpar e o comprimento da última lista é igual à primeira entrada.
Uma entrada de 5 resultaria em[[9], [9, 9, 9], [9, 9, 9, 9, 9]]

[DOO²Q#ćD_Piˆëć<¸«¸ì]
Em seguida, iteramos sobre essas listas, diminuindo os elementos em uma lista até que a lista consista apenas em zeros e depois na próxima. Paramos quando a soma total é igual à segunda entrada.

[     #              ]   # loop until
 DOO                     # the sum of the list of lists
    ²Q                   # equals the second input
        ć                # extract the first list
         D_Pi            # if the product of the logical negation of all elements is true
             ˆ           # add the list to the global list
              ë          # else
               ć<        # extract the head and decrement it
                 ¸«      # append it to the list
                   ¸ì    # and prepend the list to the list of lists

Agora, precisamos desordenar a lista final simulando a remoção de elementos de lados alternados, em vez de da esquerda para a direita, como temos feito.

ć                   # extract the row we need to sort
 ā<                 # push a list of indices of the elements [0 ... len(list)-1]
   ΣÉ}              # sort it by even-ness
      2äćR¸ì˜       # reverse the run of even numbers
                    # the resulting list will have 0 in the middle,
                      odd number increasing to the right and
                      even numbers increasing to the left
             è      # index into our final row with this
              ¸ì¯ì  # reattach all the rows to eachother

Agora formatamos a saída corretamente

J              # join list of lists to list of strings
 DSOIα         # calculate the absolute difference of sum of our triangle and the 3rd input
      '-‚ì     # pair it with the string "-" and append to the list of rows
          .C   # join by newlines and center each row
Emigna
fonte
Verdade? Isso foi complicado?
Urna Mágica do Polvo
@MagicOctopusUrn: Você é muito bem-vindo em superar-me :) Algumas coisas sobre esse método se tornaram um pouco confusas devido às peculiaridades da linguagem que eu não encontrei uma maneira melhor de contornar. Talvez haja uma maneira melhor de tudo? Talvez algo mais matemático?
Emigna
Eu estava pensando em usar números binários de alguma forma ... não pensei completamente, não tinha uma hora livre.
Magic Octopus Urn
Já faz um tempo desde que tentei superar uma das suas soluções com mais de 20 bytes. Fiquei com vergonha de admitir, mas quando vejo suas respostas, geralmente não perco o tempo tentando encontrar melhorias; porque geralmente não consigo encontrar nenhum hah!
Magic Octopus Urn
@MagicOctopusUrn: Muito ruim. Você geralmente consegue apresentar alternativas interessantes (e / ou melhorias) para minhas soluções. Programas grandes em idiomas de golfe são certamente mais difíceis de dedicar um tempo para trabalhar com certeza.
Emigna
5

Limpo , 305 289 bytes

import StdEnv
@[h:t]|all((==)9)h|t>[]=[h: @t]=[h]
#s=length h/2
#m=hd(sort h)+1
=[updateAt(hd[e\\e<-flatten[[s+i,s-i]\\i<-[0..s]]|h!!e<m])m h:t]
$a b c=flatlines(map(cjustify(a+1))[fromString(fromInt(b-c)),['-']:reverse(map(map(toChar o(+)48))((iterate@[repeatn(a-r)0\\r<-[0,2..a]])!!c))])

Experimente online!

Furioso
fonte
1
@KevinCruijssen Fixed.
Οurous
1

Perl 5 , 301 bytes

($x,$t,$u)=<>;$s=$x;$t-=$g=$t>$u?$u:$t;while($s>0){@{$a[++$i]}=((0)x$s,($")x($x-$s));$a[$i][$_%$s]++for 0..($f=$g<$s*9?$g:$s*9)-1;$g-=$f;$s-=2}say$"x(($x-length($g+=$t))/2+.5),$g,$/,$"x($x/2),'-';while(@b=@{pop@a}){for($i=1;$i<@b;$i+=2){print$b[-$i]}print$b[0];for($i=1;$i<@b;$i+=2){print$b[$i]}say''}

Experimente online!

Xcali
fonte
1

Carvão , 68 63 62 bytes

NθNηNζF⊘⊕θF⁹F⁻θ⊗ι«J⊘⎇﹪λ²⊕λ±λ±ι≔¬¬ζλ↑I⁺λIKK≧⁻λη≧⁻λζ»↑-M⊘⊖LIη←Iη

Experimente online! Link é a versão detalhada do código. Editar: salvou 5 bytes removendo a verificação do intervalo de índice agora desnecessário. Explicação:

NθNηNζ

Insira o comprimento em q, o número de grãos de areia he o índice em z.

F⊘⊕θF⁹F⁻θ⊗ι«

Faça um loop nas (q+1)/2linhas (de baixo para cima), depois 9 grãos em cada célula da linha e depois faça um loop nos dígitos da linha.

J⊘⎇﹪λ²⊕λ±λ±ι

Salte para o dígito.

≔¬¬ζλ↑I⁺λIKK≧⁻λη≧⁻λζ»

Se possível, distribua um grão de areia para esse dígito, diminuindo a quantidade de areia e o índice restante. Se passamos o índice, isso ainda converte espaços em zeros, preenchendo a ampulheta. O dígito é impresso para cima, porque isso significa que o cursor estará no pescoço após o último dígito.

↑-

Imprima o pescoço.

M⊘⊖LIη←Iη

Centralize e imprima a quantidade de areia restante.

Neil
fonte