cinpush
main:
gte Hans 1s Leopold
jnz Leopold done
mov 1s Hans
gte Gertrude Hans Leopold
jnz Leopold done
mov Gertrude ShabbySam
mov Hans Gertrude
mov ShabbySam Hans
gte Alberto Gertrude Leopold
jnz Leopold done
mov Alberto ShabbySam
mov Gertrude Alberto
mov ShabbySam Gertrude
done:
mov 10 ShabbySam
gte 1s ShabbySam Leopold
jz Leopold undo_u
mov 30 ShabbySam
gte 1s ShabbySam Leopold
jz Leopold undo_d
undo_r:
POP!! 1
"shuffle" f
"shuffle" f
"shuffle" b
"shuffle" b
"shuffle" l
"shuffle" f
"shuffle" f
"shuffle" b
"shuffle" b
jmp end
undo_u:
POP!! 1
"shuffle" f
"shuffle" f
"shuffle" f
"shuffle" b
"shuffle" b
"shuffle" b
"shuffle" l
"shuffle" l
"shuffle" l
"shuffle" f
"shuffle" b
jmp end
undo_d:
POP!! 1
"shuffle" f
"shuffle" b
"shuffle" l
"shuffle" f
"shuffle" f
"shuffle" f
"shuffle" b
"shuffle" b
"shuffle" b
end:
jnz 1s main
print Hans
done!
Esto fue muy divertido, ¡gracias Liam! :)
Gracias a Sp3000 por un ligero pero necesario empujón en la dirección correcta.
¿Cómo?
Dos palabras: Cubo de bolsillo .
Resulta que las pilas corresponden a las caras de un cubo de Rubik 2x2x2 de la siguiente manera:
____ ____
| | |
| 19 | 17 |
|____U____|
| | |
| 20 | 18 |
_________|____|____|____ ____ ____ ____
| | | | | | | | |
| 13 | 14 | 1 | 2 | 9 | 10 | 6 | 5 |
|____L____|____F____|____R____|____B____|
| | | | | | | | |
| 15 | 16 | 3 | 4 | 11 | 12 | 8 | 7 |
|____|____|____|____|____|____|____|____|
| | |
| 22 | 24 |
|____D____|
| | |
| 21 | 23 |
|____|____|
Donde ULFRBD
indique qué cara corresponde a arriba, izquierda, adelante, derecha, atrás, abajo cuando el cubo se pliega correctamente.
Las permutaciones corresponden a rotar cualquier lado 90 grados (donde afortunadamente los nombres coinciden). Resulta que f
, r
y d
son rotaciones en sentido horario (cuando se ve la cara) y r
, l
y u
son rotaciones en sentido antihorario (cuando se ve la cara).
Ahora el cinpush
comando funciona de tal manera que aplica una de las rotaciones u
, d
o r
(dependiendo del valor dado) y luego empuja el valor de entrada a la pila en su posición 1
. (Y luego se repite haciendo esto para cada elemento en la entrada). Eso significa que podemos revertir este proceso (para asegurarnos de que terminemos con el orden correcto de las pilas sin tener que resolver un cubo arbitrario de Rubik) mirando repetidamente la pila en posición 1
, deshaciendo la permutación correspondiente y haciendo estallar el valor de esa pila (de modo que la próxima vez que veamos la pila, obtengamos el valor debajo).
¿Cómo deshacemos las rotaciones? Afortunadamente, tenemos ambos f
y b
a nuestra disposición. Si aplicamos ambos, rotamos todo el cubo 90 grados. Esto significa que podemos mover el lado afectado ( U
, R
o D
) a L
, deshacer la rotación usando uno o tres l
s (dependiendo de la dirección relativa de l
y la rotación se realiza durante la entrada) y, a continuación, girar la parte posterior del cubo a su orientación anterior utilizando f
y b
otra vez.
En particular, cada una de las rotaciones realizadas durante la entrada se puede deshacer de la siguiente manera:
u --> fffbbblllfb
r --> ffbblffbb
d --> fblfffbbb
Veré si puedo encontrar algunas animaciones para mostrar que esto funciona.
Ahora esto nos da una forma de iterar a través de toda la entrada una vez. Pero con 5 registros, eso es todo lo que necesitamos:
Alberto
es el valor máximo encontrado hasta ahora.
Gertrude
es el segundo valor más grande encontrado hasta ahora.
Hans
es el tercer valor más grande encontrado hasta ahora.
Cuando encontramos un nuevo valor, aumentamos esos tres hasta donde sea necesario, donde podemos usarlo ShabbySam
como un registro temporal para los swaps. Eso todavía deja Leopold
lo que podemos usar para mantener un condicional al hacer las comparaciones necesarias.
Al final del proceso, simplemente imprimimos el contenido de Hans
, que ya tendrá el tercer valor más grande.
TKDYNS por Sam Cappleman-Lynes
Esto probablemente no sea óptimo, pero creo que hace el truco ...
Esto puede ser una sorpresa, pero no escribí esto a mano ... el código fue generado por el siguiente programa de Mathematica:
De hecho, escribí todas esas
safetyCheck
líneas a mano. Pero la primera línea de ese código de Mathematica tiene en realidad unos 28,000 caracteres y fue generada por el siguiente código CJam:(Que toma como entrada los 10 diseños codificados en el intérprete. Puede ejecutar el código en línea ) .
Código-generación-ception!
Explicación
Para empezar, eche un vistazo a este script de CJam para ver cómo se ven los laberintos.
Mi solución se basa en una observación importante: siempre que recojamos elementos a lo largo de una sola columna, no cambiaremos entre diseños, independientemente de si las celdas están llenas o no. En particular, mientras nos movemos a lo largo de la columna más a la izquierda, permaneceremos en el diseño
0
. Mientras nos movemos a lo largo de la siguiente columna, permaneceremos en el diseño1
.La parte difícil es cómo asegurarnos de que hayamos cambiado entre diseños, porque no sabemos qué celdas de la columna
1
tienen elementos (¡si es que hay alguno!).Así que aquí está el algoritmo (comenzando en la celda
0
en el diseño0
):Ahora, para cada celda a la derecha de la columna actual (probándolas en el orden principal de la columna), intente moverse allí en el diseño actual, seleccione un elemento allí, luego muévase a la fila superior en esa nueva columna usando el nuevo diseño.
Si el intento de celda contenía un elemento, el diseño habrá cambiado y llegaremos con éxito a la nueva columna y diseño. Debido a que la nueva posición (segura) está en la fila superior, pero todos los intentos de encontrar la siguiente columna incluyen 10 movimientos netos hacia arriba, todos los demás intentos fallarán, por lo que podemos ignorarlos.
Si el intento de celda no contenía un elemento, en la mayoría de los casos, el súbdito morirá durante el intento de llegar a la fila superior usando el diseño incorrecto, descartando este intento. Sin embargo, este no es siempre el caso. Por ejemplo, el intento de celda podría estar ya en la fila superior, por lo que no se realizaron movimientos en el nuevo diseño. Del mismo modo, en algunos casos, la ruta desde la celda intentada hasta la fila superior es lo suficientemente corta como para ser válida en ambos diseños. He recopilado todos los casos en los que esto es un problema a mano, y determiné un conjunto de movimientos que solo es válido en el nuevo diseño (pero que mueve al minion de nuevo a la celda objetivo, por lo que es efectivamente un no-op en el nuevo diseño). Después de cada intento donde esto puede ser un problema, realizo este conjunto de movimientos para matar a los secuaces que no
Ahora nos hemos movido con éxito a la parte superior de la siguiente columna que contiene al menos un elemento. Regrese al paso 1.
Puede notar que la estructura de la solución es la siguiente:
En cuanto al código de Mathematica, las
safetyCheck
cadenas son esos movimientos seleccionados a mano que aseguran que hayamos alcanzado el nuevo diseño. El primer parámetro para la búsqueda es el diseño desde el que comenzamos y el segundo es la celda que hemos intentado. Las combinaciones que no se mencionan explícitamente solo dan una comprobación de seguridad vacía (porque no es necesaria).Además de eso, simplemente estoy configurando los 10 laberintos como
Graph
objetos, donde hay dos bordes dirigidos entre las celdas adyacentes (y conectadas), donde cada borde se anota con el movimiento requerido para atravesar el borde. Con eso en su lugar, simplemente puedo encontrar las rutas usandoFindShortestPath
y luego extraer las etiquetas de borde correspondientes conPropertyValue[..., EdgeLabels]
.El resto del código solo usa eso para implementar el algoritmo anterior de manera bastante directa.
Los datos reales del gráfico se almacenan
layouts
y se generaron con el script CJam, que decodifica los números como se describe en la publicación del policía y los convierte en una lista de Mathematica, que puede transformarse fácilmente en un gráfico.fuente
HPR, por Zgarb
El código:
Primero que nada ... el código fue generado, no escrito a mano (o escrito).
Datos sobre el idioma:
El programa utiliza el siguiente psuedocode:
El entorno casi siempre contiene solo 1 lista y 1 entero.
Para resolver esto, creé un pequeño motor de macro para este lenguaje. También permite comentarios. Aquí está el motor de macro:
Después de construir el motor de macros, lentamente desarrollé funciones útiles para este lenguaje. Aquí está el código que el motor procesó para crear el programa:
fuente
Brian y Chuck por Martin Büttner
El siguiente programa Python 2.7 genera mi programa Brian & Chuck, traduciendo un programa brainfuck a Brian & Chuck (con la excepción de que
.
siempre se imprime1
, ya que ese es el único personaje que necesitamos generar).El flujo de control funciona por
artedemagiahaciendo que Brian escriba en los comandos de cinta de Chuck para enviar a Brian a la posición correcta en el código.Tenga en cuenta que los espacios en blanco y los correos electrónicos
[]
agregados al programa B&C son solo decorativos.fuente
Firetype, por kirbyfan64sos
Código de trabajo comentado:
Esto se basa en el intérprete de lo previsto actualmente en la respuesta de la policía, lo que contradice un poco con respecto a la documentación
%
y!
.El principal desafío aquí fue analizar la entrada, ya que
\
hace que encontrar el tercer valor más grande sea bastante simple.fuente
Acc !, por DLosc
Este idioma tiene un terrible soporte de comparación.
Las
count [varname] while 0
declaraciones al principio son para declarar la variable que contiene el número más grande, el segundo número más grande, el tercer número más grande, y así sucesivamente. Las comparaciones se logran restando los dos números y luego verificando si el resultado es negativo, verificando si es un número menor10^6
.fuente
Zinc, por kirbyfan64sos
Esto no fue tan difícil, una vez que entendí cómo funciona el lenguaje. La parte difícil fue superar los errores del analizador, pero agregar algunos paréntesis superfluos parecía solucionarlo. Aquí está la solución:
Explicación
En la primera y segunda fila, defino
+
ser lacut
operación. El resto son comprensiones establecidas. Tomemos la entrada101011101100
como ejemplo, y comencemos desde el más interno:Esto toma esos elementos
a
del conjunto de entradaS = {1,0,1,0,1,1,1,0,1,1,0,0}
cuyo índice no eslen(S)-1
, así que todos menos el último. Noté que esto también invierte el conjunto, por lo que el resultado esA = {0,1,1,0,1,1,1,0,1,0,1}
. Luego, la comprensióntoma todos los elementos
A
excepto el primero y lo invierte nuevamente, lo que resulta enB = {1,0,1,0,1,1,1,0,1,1}
. Luego, nos dividimosB
en la0
s (esto da como resultado{1,1,{1,1,1},{1,1}}
o su inversión, no verifiqué cuál), y clasificamos el resultado por longitud. Los conjuntos Singleton se aplanan, pero todos son1
s, por lo que su longitud sigue siendo 1. Aquí está el código:El resultado de esto es
C = {{1,1,1},{1,1},1,1}
. Finalmente, filtramos todo excepto el elemento en el índice 2 porEsto resulta en el conjunto
D = {1}
de nuestro caso. En general, puede tener la forma{{1,1,..,1}}
, pero esto no importa ya que solo1
se imprimen los s.fuente
Sopa de brújula, por BMac
Esto fue divertido.
Editar: este programa debe anteponerse con una nueva línea para poder trabajar en el intérprete de BMac. Parece que no puedo hacer que la nueva línea aparezca en el bloque de código.
El programa se divide en 4 secciones de ejecución.
El primero, en la línea 1, agrega
#
a al final de la entrada al encontrar00
y reemplazar el segundo0
con#
. También cambia todos los1
s aA
s, ya que quería tener la menor cantidad posible de1
s en el código fuente.La segunda sección, en la línea 5, obtiene el segundo número en la entrada y lo coloca debajo del primer número como una cadena de
+
s. Por ejemplo, si la entrada es11011101100
, entonces resultará en lo siguiente:La tercera sección, en la línea 12, combina la cadena de
+
s con el primer número: cada uno0
encima de se+
convierteA
, seA
convierteB
, seB
convierteC
yC
permanece sin cambios. Luego, volvemos a la segunda sección para buscar el siguiente número.Una vez que todos los números se han combinado de esta manera, llegamos a la sección final en la línea 18. El número de
C
s es nuestra salida deseada, por lo que los cambiamos a1
s, omitiendo el primeroC
porque hay un único1
en el código fuente que se imprime a lo largo con la salidafuente