Koopa Shell Sequence

19

Em vários jogos de Super Mario , as conchas de Koopa Troopa verdes e vermelhas podem deslizar sem atrito em superfícies planas e destruir blocos de tijolos que estão em seu caminho. Quando uma concha atinge um bloco de tijolos, o bloco quebra, transformando-o em espaço vazio, e a concha de Koopa inverte a direção. Como exemplo, assista à concha vermelha aqui .

Suponha que um nível de Super Mario tenha apenas um bloco de altura e cada célula da grade seja um tijolo ou um espaço vazio, exceto a célula mais à esquerda, que contém uma concha que se move para a direita. O nível também é periódico ; portanto, se o shell sair da borda direita ou esquerda do nível, ele entrará novamente no lado oposto. Nesta situação, o projétil continuará ricocheteando e quebrando todos os blocos de tijolos no nível até que não haja mais. Até onde a casca viajou logo após o último bloco de tijolos ser quebrado?

Desafio

Escreva um programa ou função que receba um número inteiro decimal não negativo. Esse número, expresso em binário sem zeros à esquerda (a única exceção é o próprio 0), codifica o layout de nível alto de um bloco. A 1é um bloco de tijolos e a 0é um espaço vazio.

O Koopa Shell é inserido na extremidade esquerda do nível e está inicialmente se movendo para a direita. Por exemplo, o nível associado à entrada 39é

>100111

porque 100111é 39 em binário, >e <representa as conchas em movimento direita e esquerda, respectivamente.

Você precisa imprimir ou retornar a distância total percorrida pelo shell depois que o último bloco de tijolos (aka 1) for quebrado.

A saída para 39é 7e as alterações no nível são assim:

Level      Cumulative Distance
>100111    0
<000111    0
>000110    0
0>00110    1
00>0110    2
000>110    3
000<010    3
00<0010    4
0<00010    5
<000010    6
000001<    7
000000>    7  <-- output

Da mesma forma, a saída para 6é 1:

Level    Cumulative Distance
>110     0
<010     0
001<     1
000>     1  <-- output

O código mais curto em bytes vence.

Para referência, aqui estão as saídas para entradas 0para 20:

0 0
1 0
2 0
3 0
4 0
5 0
6 1
7 1
8 0
9 0
10 1
11 2
12 2
13 1
14 3
15 3
16 0
17 0
18 1
19 3
20 2

E aqui estão as saídas até a entrada 1000.

Passatempos de Calvin
fonte

Respostas:

6

CJam, 29 26 24 bytes

Agradecimentos ao Sp3000 por salvar 3 bytes.

q~2b{_1&}{W\({%}*0+}w],(

Suíte de teste. (Isso imprime todos os resultados de 0 ao número inteiro fornecido em STDIN.)

Explicação

Isso inverte um pouco a especificação: em vez de mover o shell pela cadeia binária, mudamos e invertemos a cadeia binária de modo que o shell esteja sempre à frente, apontando para a direita:

q~      e# Read and evaluate the input.
2b      e# Convert to base-2 to get the "level".
{_1&}{  e# While there is a 1 in the level...
  W\    e#   Put a -1 below the level.
  (     e#   Pull off the first digit, i.e. the cell the shell is pointing at.
  {     e#   If it's a 1 (i.e. a brick)...
    %   e#     Reverse the level, consuming the -1. This isequivalent to reversing the 
        e#     shell in place.
  }*
  0+    e#   Append a zero. If the cell was a brick, this just replaces it with an empty
        e#   cell. Otherwise, this rotates the level by one cell. This is equivalent 
        e#   to moving the shell one cell through the periodic level.
        e#   Note that if the leading cell was 0, the -1 remains on the stack.
}w
],(     e# Wrap the stack in an array, get its length and decrement.
Martin Ender
fonte
5

Pitão, 24 bytes

&.WsH_XZeaYxZ1 0jQ2ssPBY

Experimente on-line: Demonstration or Test Suite

O código de 22 bytes a seguir também deve fazer o truque. Ele não funciona atualmente, devido a um erro no compilador Pyth.

&u_XGeaYxG1ZjQ2)ssPBPY

edit: Bug corrigido, mas é claro que a solução não conta.

Experimente on-line: Demonstration or Test Suite

Explicação:

Alternando de frente e de trás, faço o seguinte:

  • Eu procuro um 1
  • Lembre-se deste índice colocando-o em uma lista
  • Atualize este 1 para um 0

Quando não há 1s, calculo a distância. Importante é: O shell move cada distância da lista duas vezes (para frente e para trás), exceto a última distância.

&.WsH_XZeaYxZ1 0jQ2ssPBY   implicit: Y = empty list
                jQ2        convert input number to binary
 .WsH                      start with Z=^; 
                           while the sum(Z) > 0, apply the the following to Z:
           xZ1                index of 1 in Z
         aY                   append this to Y
        e                     take the last element of Y (=this index)
      XZ       0              set this 1 (at index ^) in Z to 0
     _                        and revert the order of Z
                           this returns a list of zeros
&                          don't print ^, print the next thing
                     PBY   creates the list [Y, Y[:-1]]
                    s      combine these lists
                   s       sum up the distances
Jakube
fonte