Introducción
Una familia de focas está varada sobre un iceberg en el Círculo Polar Ártico. Hay un transmisor de radio ubicado en el iceberg que los sellos pueden usar para pedir ayuda. Sin embargo, solo el sello de papá sabe cómo operar el transmisor de radio. Y lo que es peor, el hielo es muy resbaladizo en esta época del año, por lo que los sellos se deslizarán sin control hasta que lleguen a otro sello o se salgan del borde del iceberg, lo que hace que sea muy difícil para el sello papá alcanzar el transmisor de radio. Afortunadamente, uno de los sellos es un científico de la computación, por lo que decide escribir un programa para descubrir cómo maniobrar el sello de papá al transmisor de radio. Como no hay mucho espacio en el hielo para escribir un programa, ella decide hacer que el programa use la menor cantidad de bytes posible.
Descripción de entrada
El programa del sello recibirá información de STDIN, argumentos de línea de comando o funciones de entrada del usuario (como raw_input()
). No se puede preinicializar en una variable (por ejemplo, "Este programa espera la entrada en una variable x
").
La primera línea de la entrada consta de dos enteros separados por comas en la forma
A,B
A continuación hay B
líneas que consisten en A
caracteres cada una. Cada línea solo puede contener caracteres de los siguientes:
.
: El frío, el frío, el océano. El mapa siempre tendrá esto como borde.#
: Una parte del iceberg.a
...z
: Un sello que no es el sello de papá en el iceberg.D
: El sello de papá en el iceberg.*
: El transmisor de radio.
(Tenga en cuenta que el sello de papá siempre se anota con una mayúscula D
. Una minúscula d
es simplemente un sello normal).
Descripción de salida
De acuerdo con las siguientes reglas con respecto a cómo se pueden mover los sellos, emite una lista de instrucciones para los sellos sobre cómo deben moverse para llevar el sello de papá al transmisor de radio.
- Regla: todos los sellos pueden moverse hacia arriba (
U
), hacia abajo (D
), hacia la izquierda (L
) y hacia la derecha (R
). No pueden deslizarse en diagonal. - Regla: Al moverse, un sello continuará moviéndose en la misma dirección hasta que choque con otro sello o caiga al mar.
- Si un sello choca con otro sello, dejará de moverse. El sello con el que chocó no se moverá.
- Si un sello cae al mar, se ahogará y desaparecerá del mapa. Es decir, no actúa como un colisionador para otros sellos y no se puede mover de nuevo.
- Regla: dos sellos no se pueden mover al mismo tiempo, tampoco se puede mover un sello mientras otro se mueve. El siguiente sello solo se puede mover una vez que el sello anterior haya dejado de moverse.
- Regla: no hay restricción con respecto a mover un sello varias veces, o el número de sellos que se ahogan.
- Regla: Una solución correcta tendrá el sello papá finales en el transmisor de radio. El sello de papá no puede simplemente pasar el transmisor mientras se desliza.
La salida constará de varias líneas, cada una en forma
A,B
¿Dónde A
está el sello de moverse ( D
para el sello papá, a
... z
para los demás), y B
es la dirección para mover el sello (o bien U
, D
, L
, o R
). Tenga en cuenta que no necesita encontrar la ruta más corta. Cualquier ruta que lleve al sello de papá a la meta es un resultado aceptable.
Ejemplo de entradas y salidas
Entrada:
25,5
.........................
.#######################.
.####D#############*k###.
.#######################.
.........................
Salida:
D,R
Entrada:
9,7
.........
.a#####b.
.#####d#.
.##l*###.
.###m#p#.
.#D#.#c#.
.........
Salida (una salida posible de muchas):
m,R
b,L
D,U
D,R
D,D
D,L
Entrada:
26,5
..........................
.###..................###.
.l*##########v#########D#.
.###..................###.
..........................
Salida (una salida posible de muchas):
v,D
D,L
Si tiene alguna otra pregunta, por favor pregunte en los comentarios.
Respuestas:
Python 3, 520 bytes
Puedo hacer una explicación más detallada más adelante si la gente lo desea, pero básicamente esto ejecuta una búsqueda profunda con profundización iterativa en el espacio de estado de posibles movimientos. Si un movimiento hace que el sello de papá se caiga, se rechaza inmediatamente. Si el papá termina al lado del transmisor, se imprime la secuencia de movimientos y el programa se divide por cero para forzar una salida.
Puedo hacer que el código se ejecute significativamente más rápido agregando
if G!=g:
al comienzo de la penúltima línea, por 8 bytes adicionales; esto rechaza los movimientos que no cambian nada, comok,L
en el primer caso de prueba.El tiempo de ejecución varía notablemente de una ejecución a la siguiente, incluso con la misma entrada, evidentemente como resultado del hecho de que elijo el siguiente sello para moverlo iterando sobre un
set
, que es un tipo desordenado. Calculé el segundo caso de prueba a los 5 minutos y 30 segundos, aunque no pareció mucho la primera vez que lo ejecuté. Con la optimización mencionada anteriormente, es más como 40 segundos.fuente
JavaScript (ES6) 322
334 323Edición2 Animación agregada en el fragmento
Editar corrección de errores, recuerde la posición inicial de '*', así que lo encuentro incluso cuando un sello se desliza sobre él y lo borro.
Implementado como una función con la cadena de entrada como parámetro (probablemente no válido pero esperando una aclaración). Salida a través de una ventana emergente.
El problema con la entrada de cadenas multilínea en JavaScript es que
prompt
no lo maneja bien.En cuanto al algoritmo: un BFS, debería encontrar una solución óptima. Mantengo una cola del estado del juego en variable
l
, el estado de la cuadrícula de personajesg
y la secuencia de movimientos hasta ahoras
. Además, hay un conjunto de cuadrículas obtenidas hasta ahora en variablek
, para evitar explorar la misma cuadrícula una y otra vez.El bucle principal es
Ejecute Snippet para probar en FireFox
Mostrar fragmento de código
fuente
C ++, 628 bytes
Bueno, esto no resultó muy corto:
Elegí C ++ porque quería usar las estructuras de datos (
set
,string
), pero es intrínsecamente bastante detallado. La solución tiene un rendimiento razonablemente bueno, resolviendo la prueba 2 en poco más de 2 segundos en un MacBook Pro, a pesar de que no está optimizado para el tiempo de ejecución.Código antes de comenzar a eliminar espacios en blanco y alguna otra reducción de longitud:
La idea central detrás del algoritmo es que se mantienen dos conjuntos:
q
es el conjunto de configuraciones que están pendientes de procesamiento.p
es el conjunto de configuraciones que se han procesado.El algoritmo comienza con la configuración inicial en
q
. En cada paso, se genera una configuraciónq
, se agrega ap
, todos los posibles movimientos de sellado se generan y se insertan las nuevas configuraciones resultantesq
.Prueba de funcionamiento:
fuente
q
ciertamente sería mejor en ese sentido. La razón por la que usé un conjunto fue porque quería evitar ingresar la misma entrada varias veces. Pero comencé a tener dudas una vez que vi el resultado.