En Twitch Plays Pokémon , uno de los obstáculos más molestos que uno puede enfrentar es un rompecabezas de hielo, en el que debe viajar de un lugar a otro deslizándose en una dirección hasta que golpee una pared o una roca.
Su tarea es construir un programa que genere un rompecabezas de hielo difícil al azar.
Su programa aceptará tres números, M
, N
, y P
, como entrada (con 10 <= M <= 30
, 15 <= N <= 40
y 0 <= P < 65536
):
12 18
y dará salida:
- Una
M
porN
rejilla que consiste en.
yO
, en representación de hielo y un canto rodado respectivamente. - Un marcador de posición que representa desde dónde se ingresa el rompecabezas. Este marcador de posición consiste en una letra
L
,R
,T
, oB
, en representación de la izquierda, derecha, superior e inferior, seguido de un número que representa la posición (desde la izquierda o la parte superior) en ese lado que se introduce desde. - Un marcador de posición similar que representa de dónde sale el rompecabezas.
- La solución más corto para el rompecabezas, que consiste en una secuencia de
L
,R
,U
, yD
respectivamente.
Salida de ejemplo:
..O...O...........
............O.....
..O...............
.......O..........
..................
...........O......
O..O...........O..
..........O.......
..O..........O....
........O.........
O....O.........O..
............O.....
R 4
B 5
LDLDRULD
(Note that this output is actually invalid because it is not actually long enough.)
Para una entrada M
y N
, la solución al rompecabezas debe tener al menos min(M, N)
pasos y mover al menos 2 (M + N)
espacios totales. (Para referencia, el rompecabezas anteriormente mueve un total de 12 pasos, moviendo 69 espacios.) Su generador rompecabezas debe generar una diferente M
por N
rompecabezas con un camino de solución diferente (es decir, una secuencia diferente de pasos para cada solución) para cada semilla P
.
- Tenga en cuenta que el requisito de una ruta de solución diferente es evitar soluciones que intenten generar sistemáticamente rutas de roca, como la solución de Claudiu aquí . Si hay dos o tres pares de soluciones idénticas debido a peculiaridades en la aleatoriedad, eso estará bien, siempre y cuando el programa no esté tratando intencionalmente de generar sistemáticamente rompecabezas con la misma secuencia de movimientos.
El código más corto para hacer lo anterior gana.
>
y<
(o cualquier carácter) para la entrada y la salida? Los rompecabezas serán más fáciles de leer.LDLDRULD
es de solo 8 pasos de largoRespuestas:
Python,
672548 caracteres, rompecabezas más interesantesAunque siguiendo estrictamente las reglas, mi otro programa de Python supera este, decidí escribir uno que generaría rompecabezas más interesantes de todos modos. Aquí está:
Los niveles de sangría son espacio, tabulación, tabulación + espacio.
Muestras :
Se utiliza
P
como semilla, por lo que cada unoP
generará el mismo rompecabezas yP
es muy probable que cada uno sea diferente:Funciona razonablemente rápido hasta tamaños,
M=25,N=40
pero más allá de eso se vuelve realmente lento. Teóricamente debería funcionarM=30, N=40
si lo dejas correr el tiempo suficiente. He escrito manualmente en el camino aquí ya que es difícil de seguir: el programa simplemente genera el rompecabezas.explicación :
El programa realiza un bucle, generando una posición de inicio aleatorio en la parte superior, una posición final aleatoria en la parte inferior y una cuadrícula aleatoria con la
12.5%
posibilidad de una roca en cualquier punto dado. Luego resuelve el rompecabezas con una búsqueda de amplitud y, si la solución existe y es más grande quemin(H,W)
, se imprime y sale.fuente
Java - 2632
Mientras admiro la pureza técnica de la respuesta de Claudiu , decidí intentar hacer rompecabezas un poco más difíciles;)
Pasos básicos (bastante simples):
También marco cada lugar como 'nogo' mientras me deslizo. Si termino en un lugar nogo (o justo en frente de uno que significaría que una roca iría allí), es un paso no válido.
Entonces, básicamente la idea es generar aleatoriamente muchos mapas y mantener el primero que sea válido. Planeo hacer esto más inteligente (retroceso, etc.), pero funciona bien en este momento. También podría reducir el código redundante, ya veremos.
Tal como está, genera mapas pequeños (15x10) casi instantáneamente, mapas medianos (30x20) en un par de segundos y grandes (40x30) en una cantidad de tiempo aleatorio entre 20 segundos y 20 minutos, dependiendo de la semilla. Prueba entre 300k-500k mapas / segundo en mi máquina, dependiendo del tamaño.
Nota al margen: a veces los mapas no son demasiado difíciles, simplemente porque solo hay tantas rocas como escalones, y a menos que el escalón te lleve a una pared, la mayoría de las veces solo hay una opción si quieres golpear una roca real. Lo arreglaré más tarde colocando rocas "aleatorias" en lugares seguros después de que se hayan dibujado todos los pasos. Como los puntos nogo ya están marcados, eso debería ser bastante simple. Por ahora, solo disfruta de estos ejemplos:
Salida que muestra diferentes tamaños / semillas:
Tamaño máximo 40x30:
Golfizado:
Con saltos de línea:
fuente
while(o<3){...;o=...;}
serfor(;o<3;o=...){...;}
, guardar un byte?if(w%2<1)return new Point(f.x,f.y+i*d);else return new Point(f.x+i*d,f.y);
->return new Point(f.x+(w%2<1?0:i*d),f.y+(w%2<1?f.y:0));
.Python,
235206185176 caracteresUso :
La entrada es a través de stdin del formulario
[M, N, P]
.Dijiste que los mapas tenían que ser diferentes para cada semilla
P
... y son:Y un ejemplo con un tamaño diferente:
Satisface todos los criterios objetivos suministrados:
P
lleva a un rompecabezas diferenteN + N%2
medidas, que es al menosN
2 (M + N)
espacios totalesexplicación :
Cada fila se construye repitiendo un cierto elemento de cadena
W
veces y limitando la longitud aW
(yo usoH
y enW
lugar deM
yN
).Las dos primeras filas dependen
P
para hacer que cada rompecabezas sea único. Básicamente, tengaP
en cuenta que cabe en un entero sin signo de 16 bits. ConviertoP
a binario, usando.
para 0 yO
para 1:El primer elemento de fila es los últimos 15 bits,
t[1:]
mientras que la segunda fila de elementos es la primera bit,t[0]
. No pude ponerlo todo en una fila porque el ancho mínimo es 15, que no encajaría en todos los 16 bits siP
> 32767. Por lo tanto, las dos primeras filas representan de forma única cada uno de los valores posibles deP
.La tercera fila es un muro completo para que el valor de
P
no afecte a la solución.Luego sigue los elementos del laberinto real. Esta línea los imprime a todos, repitiéndolos hasta la tapa. El resultado es como ves arriba:
El resto solo estaba descubriendo cómo resolver el laberinto generado dinámicamente. Esto depende solo del ancho del laberinto. Noté que las soluciones, para un ancho dado, eran:
etc Por lo tanto es sólo
URDR
repite y se cortó en el lugar correcto,W+W%2
.fuente