Secuencia de conchas de Koopa

19

En varios juegos de Super Mario , las conchas Koopa Troopa verdes y rojas pueden deslizarse sin fricción sobre superficies planas y destruir bloques de ladrillos que se encuentran en su camino. Cuando un caparazón golpea un bloque de ladrillos, el bloque se rompe, convirtiéndolo en un espacio vacío, y el caparazón de Koopa invierte la dirección. Como ejemplo, mira el caparazón rojo aquí .

Supongamos que un nivel de Super Mario tiene solo un bloque de altura y cada celda de la cuadrícula es un ladrillo o un espacio vacío, excepto la celda más a la izquierda que contiene un caparazón que se mueve hacia la derecha. El nivel también es periódico , por lo que si el caparazón sale del borde derecho o izquierdo del nivel, volverá a ingresar en el lado opuesto. En esta situación, el caparazón continuará rebotando y romperá todos los bloques de ladrillo en el nivel hasta que no haya más. ¿Qué distancia habrá recorrido el caparazón justo después de que se rompa el último bloque de ladrillo?

Desafío

Escriba un programa o función que tome un entero decimal no negativo. Este número, expresado en binario sin ceros a la izquierda (la única excepción es 0 en sí mismo), codifica el diseño de nivel alto de un bloque. A 1es un bloque de ladrillo y a 0es un espacio vacío.

El Koopa Shell se inserta en el borde izquierdo del nivel e inicialmente se mueve hacia la derecha. Por ejemplo, el nivel asociado con la entrada 39es

>100111

porque 100111es 39 en binario, >y <representan conchas móviles derecha e izquierda respectivamente.

Debe imprimir o devolver la distancia total recorrida por el caparazón una vez que 1se haya roto el último bloque de ladrillo (también conocido como ).

La salida para 39es 7y los cambios en el nivel se ven así:

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

Del mismo modo, la salida para 6es 1:

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

El código más corto en bytes gana.

Como referencia, aquí están las salidas para entradas 0a 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

Y aquí están las salidas hasta la entrada 1000.

Pasatiempos de Calvin
fuente

Respuestas:

6

CJam, 29 26 24 bytes

Gracias a Sp3000 por guardar 3 bytes.

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

Banco de pruebas. (Esto imprime todos los resultados desde 0 hasta el entero dado en STDIN).

Explicación

Esto gira un poco la especificación en su cabeza: en lugar de mover el shell a través de la cadena binaria, cambiamos e invertimos la cadena binaria de modo que el shell siempre esté al frente, apuntando hacia la derecha:

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
fuente
5

Pyth, 24 bytes

&.WsH_XZeaYxZ1 0jQ2ssPBY

Pruébelo en línea: Demostración o conjunto de pruebas

El siguiente código de 22 bytes también debería hacer el truco. Actualmente no funciona debido a un error en el compilador Pyth.

&u_XGeaYxG1ZjQ2)ssPBPY

editar: Error corregido, pero por supuesto la solución no cuenta.

Pruébelo en línea: Demostración o conjunto de pruebas

Explicación:

Alternando desde el frente y la parte posterior, hago lo siguiente:

  • Busco un 1
  • Recuerde este índice poniéndolo en una lista
  • Actualiza este 1 a un 0

Cuando no quedan 1s, calculo la distancia. Importante es: el shell mueve cada distancia en la lista dos veces (hacia adelante y hacia atrás), excepto la última distancia.

&.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
fuente