Ce défi vous fera compter les «créatures» dans le jeu de tuiles Palago.
Une créature est une forme fermée qui peut être formée par des tuiles Palago de couleur assortie dans une grille hexagonale.
Le jeu Palago se compose de tuiles comme ceci:
Ces tuiles peuvent être tournées de , , ou pas du tout, et placées n'importe où sur une grille hexagonale. Par exemple, voici une créature (rouge) qui nécessite 12 tuiles.
Défi
Le but de ce défi est d'écrire un programme qui prend un entier n
en entrée et calcule le nombre de créatures (jusqu'à la rotation et la réflexion) qui nécessitent des n
tuiles. Le programme devrait être capable de gérer jusqu'à n=10
sur TIO . Il s'agit de code-golf , donc le moins d'octets gagne.
Exemples de données
Les valeurs doivent correspondre aux données trouvées dans la section "Nombre de créatures et estimations" du site Web du créateur . À savoir
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
la source
n=10
TIO." - s'il s'agit d'une exigence de vitesse d'exécution, veuillez utiliser code-challenge au lieu de code-golf , ce dernier faisant référence à une tâche d'optimisation d'octets purs.Réponses:
JavaScript (Node.js) ,
480417 octets-63 octets grâce à @Arnauld. Sensationnel.
Essayez-le en ligne!
Tout d'abord, respectez Arnauld dont la réponse m'a donné l'inspiration pour creuser plus profondément. J'ai beaucoup essayé d'être original avec mes algorithmes, bien que j'ai intentionnellement changé une partie de mon code pour utiliser les mêmes variables qu'Arnauld afin que le code puisse être plus facilement comparé.
Recherche d'hexagones vides
La recherche de créatures est:
La recherche d'hexagones vides a révélé une symétrie intéressante. Arnauld a découvert que l'une des six directions pouvait être ignorée, mais en fait trois sur six peuvent être ignorées!
Voici la direction d'origine et la clé de tuile d'Arnauld:
Imaginez que nous commençons à la tuile A de type 1 au point bleu. Il semble que nous devions reprendre en d = 0 et d = 5. Cependant, quelle que soit la tuile placée en d = 0, elle aura certainement une sortie en d = 4, qui visitera le même hex que la tuile A sortant en d = 5. C'est la découverte d'Arnauld, et c'est ce qui m'a fait réfléchir.
Remarquerez que:
Chaque tuile qui a une sortie en d = 4 a une sortie en d = 3
Chaque tuile qui peut être entrée à partir de d = 0 a une sortie dans d = 4
Cela signifie que nous devons seulement considérer les directions 0,2,4. Toutes les sorties dans les directions 1,3,5 peuvent être ignorées car les hexs accessibles dans les directions 1,3,5 peuvent à la place être atteints à partir d'un hex adjacent en utilisant les directions 0,2 ou 4.
À quel point cela est cool!?
Directions réétiquetées
J'ai donc réétiqueté les directions et les tuiles comme ceci (image d'Arnauld modifiée):
Nous avons maintenant la relation suivante entre les tuiles, les entrées et les sorties:
Les sorties sont donc: d + t == 2? (4-t)% 3: 2-t et 2 * t% 3
Rotations et réflexions hexagonales
Pour les rotations et les réflexions, j'ai décidé d'essayer les coordonnées axiales hexagonales x, y au lieu des coordonnées du cube x, y, z.
Dans ce système, la rotation et la réflexion étaient plus simples que ce à quoi je m'attendais:
Pour obtenir toutes les combinaisons que j'ai effectuées: pourriture, pourriture, pourriture, réflexion, pourriture, pourriture
Code (480 octets d'origine)
Code (Arnauld 417 octets)
Arnauld a gentiment soumis une économie de 63 octets qui a utilisé des astuces qui m'ont pris un certain temps pour envelopper ma tête. Puisqu'il a beaucoup de modifications intéressantes, j'ai pensé mettre son code ci-dessous (j'ai ajouté mes commentaires) afin qu'il puisse être contrasté avec ma version.
la source
JavaScript (Node.js) ,
578 ... 433431 octetsComment?
Directions et tuiles
Nous utilisons les codes suivants pour la boussole à 6 directions et les tuiles:
Nous supposons que la créature est bleue.
Connexions
Nous avons besoin d'une table pour savoir quelles parties de la créature doivent être connectées à d'autres tuiles lorsque nous entrons dans une tuile donnée dans une direction donnée:
Exemple:
Une fois aplati, cela donne:
Coordonnées
Crédits: www.redblobgames.com
Cela facilitera le traitement des rotations et des réflexions lors de la dernière étape de l'algorithme.
Encodage des tuiles
Les tuiles sont stockées dans une liste, sans ordre spécifique. Cela signifie que nous n'avons pas à nous soucier d'une allocation 2D dynamique et que nous pouvons facilement itérer sur les tuiles existantes. L'inconvénient est que, compte tenu des coordonnées spécifiques, nous avons besoin de
find()
la tuile correspondante dans la liste.Algorithme
On commence avec une seule tuile de type1 ( 0 , 0 , 0 ) 0
Par conséquent, cette tuile est codée comme
[0,0,0,1,1]
.A chaque itération, nous recherchons:
Tuiles avec des connexions manquantes: dans ce cas, nous essayons successivement de compléter la connexion avec chaque type de tuile.
Tuiles qui sont déjà connectées mais pour lesquelles de nouvelles connexions doivent être ajoutées car elles ont été atteintes dans une direction différente: dans ce cas, nous mettons à jour le masque de direction (avec un OU au niveau du bit) et forçons une nouvelle itération.
Si toutes les connexions sont valides et que nous avons atteint le nombre de tuiles demandé, nous devons encore tester s'il s'agit d'une nouvelle créature ou simplement d'une version modifiée d'une créature existante:
Nous appliquons les transformations suivantes:
Nous trions les tuiles selon leurs coordonnées et types. (Ce tri est traité dans l'ordre lexicographique, ce qui est bien.)
Nous contraignons finalement la liste résultante à une chaîne de clés qui peut être comparée avec les autres clés.
Nous abandonnons dès qu'une clé connue est mise en correspondance, ou stockons la nouvelle clé et incrémentons le résultat final si aucune des transformations ne conduit à une clé connue.
Commenté
la source