Este desafío hará que cuentes "criaturas" en el juego de fichas Palago.
Una criatura es cualquier forma cerrada que puede estar formada por fichas de Palago de color coincidente en una cuadrícula hexagonal.
El juego Palago consta de fichas como esta:
Estas fichas se pueden rotar , , o no girar en absoluto, y colocarlas en cualquier lugar de una cuadrícula hexagonal. Por ejemplo, aquí hay una criatura (roja) que requiere 12 fichas.
Desafío
El objetivo de este desafío es escribir un programa que tome un número entero n
como entrada y calcule el número de criaturas (hasta la rotación y la reflexión) que requieren n
mosaicos. El programa debe ser capaz de manejar hasta n=10
el TIO . Este es el código de golf , por lo que gana menos bytes.
Datos de ejemplo
Los valores deben coincidir con los datos encontrados en la sección "Recuentos y estimaciones de criaturas" del sitio web del creador . A saber
n | output
---+-------
1 | 0
2 | 0
3 | 1
4 | 0
5 | 1
6 | 1
7 | 2
8 | 2
9 | 9
10 | 13
11 | 37
12 | 81
fuente
n=10
TIO". - si ese es un requisito de velocidad de ejecución, utilice code-challenge en lugar de code-golf , este último se refiere a una tarea de optimización de byte puro.Respuestas:
Javascript (Node.js) ,
480417 bytes-63 bytes gracias a @Arnauld. Guau.
Pruébalo en línea!
En primer lugar, respeto a Arnauld, cuya respuesta me inspiró a profundizar. He intentado ser original con mis algoritmos, aunque cambié intencionalmente parte de mi código para usar las mismas variables que Arnauld para que el código pudiera compararse más fácilmente.
Buscando hexes vacíos
La búsqueda de criaturas es:
La búsqueda de hexes vacíos descubrió una simetría interesante. Arnauld descubrió que una de las seis direcciones podría ignorarse, pero de hecho, ¡tres de cada seis pueden ignorarse!
Aquí está la dirección original y la clave de mosaico de Arnauld:
Imagina que comenzamos en el mosaico A del tipo 1 en el punto azul. Parece que tenemos que recurrir en d = 0 yd = 5. Sin embargo, cualquiera que sea la casilla colocada en d = 0, ciertamente tendrá una salida en d = 4, que visitará el mismo hexágono que la ficha A existente en d = 5. Ese es el descubrimiento de Arnauld, y es lo que me hizo pensar.
Darse cuenta de:
Cada ficha que tiene una salida en d = 4 tiene una salida en d = 3
Cada mosaico que se puede ingresar desde d = 0 tiene una salida en d = 4
Esto significa que solo necesitamos considerar las direcciones 0,2,4. Cualquier salida en las direcciones 1,3,5 se puede ignorar porque los hexes alcanzables en las direcciones 1,3,5 se pueden alcanzar desde un hex adyacente usando las direcciones 0,2 o 4.
¿¡Cuan genial es eso!?
Direcciones reetiquetadas
Así que vuelvo a etiquetar las instrucciones y los mosaicos como este (imagen editada de Arnauld):
Ahora tenemos la siguiente relación entre mosaicos, entradas y salidas:
Entonces las salidas son: d + t == 2? (4-t)% 3: 2-t y 2 * t% 3
Rotaciones Hexagonales y Reflexiones
Para rotaciones y reflexiones, decidí probar las coordenadas axiales hexagonales x, y en lugar de las coordenadas del cubo x, y, z.
En este sistema, la rotación y la reflexión fueron más simples de lo que esperaba:
Para obtener todas las combinaciones que realicé: putrefacción, putrefacción, putrefacción, reflexión, putrefacción, putrefacción
Código (480 bytes original)
Código (Arnauld 417 byte)
Arnauld presentó amablemente un ahorro de 63 bytes que utilizó trucos que me tomaron bastante tiempo para comprender. Como tiene muchas ediciones interesantes, pensé en poner su código a continuación (agregué mis comentarios) para poder compararlo con mi versión.
fuente
JavaScript (Node.js) ,
578 ... 433431 bytes¿Cómo?
Direcciones y azulejos
Utilizamos los siguientes códigos para la brújula de 6 direcciones y los mosaicos:
Asumimos que la criatura es azul.
Conexiones
Necesitamos una tabla para saber qué partes de la criatura deben conectarse a otras fichas cuando ingresamos a una ficha dada en una dirección determinada:
Ejemplo:
Una vez aplanado, esto da:
Coordenadas
Créditos: www.redblobgames.com
Facilitará el procesamiento de rotaciones y reflexiones en el paso final del algoritmo.
Codificación de mosaico
Los mosaicos se almacenan en una lista, sin un orden específico. Significa que no tenemos que preocuparnos por alguna asignación dinámica en 2D y podemos iterar fácilmente en los mosaicos existentes. La desventaja es que, dadas las coordenadas específicas, necesitamos
find()
el mosaico correspondiente en la lista.Algoritmo
Por lo tanto, este mosaico está codificado como
[0,0,0,1,1]
.En cada iteración, buscamos:
Mosaicos con conexiones faltantes: en este caso, intentamos sucesivamente completar la conexión con cada tipo de mosaico.
Mosaicos que ya están conectados pero para los cuales se deben agregar nuevas conexiones porque se han alcanzado en una dirección diferente: en este caso, actualizamos la máscara de dirección (con un OR a nivel de bits) y forzamos una nueva iteración.
Si todas las conexiones son válidas y hemos alcanzado el número solicitado de mosaicos, aún debemos probar si es una nueva criatura o simplemente una versión modificada de una existente:
Aplicamos las siguientes transformaciones:
Clasificamos los mosaicos de acuerdo con sus coordenadas y tipos. (Este tipo se procesa en orden lexicográfico, lo cual está bien).
Finalmente coaccionamos la lista resultante a una cadena de clave que se puede comparar con las otras claves.
Abortamos tan pronto como una clave conocida coincida, o almacenamos la nueva clave e incrementamos el resultado final si ninguna de las transformaciones conduce a una clave conocida.
Comentado
fuente