Dessiner le triangle de Sierpinski a été fait à mort . Nous pouvons cependant faire d’autres choses intéressantes. Si nous plions les yeux au triangle, nous pouvons voir les triangles à l'envers comme des nœuds d'un graphe fractal. Trouvons notre chemin autour de ce graphique!
Premièrement, assignons un numéro à chaque nœud. Le triangle inversé le plus grand sera le nœud zéro, puis nous descendons couche par couche (largeur d'abord) en attribuant des nombres consécutifs dans l'ordre haut-gauche-droite:
Cliquez pour une version plus grande où les petits nombres sont un peu moins flous.
(Bien sûr, ce modèle continue à l' infini dans les triangles bleus.) Une autre façon de définir la numérotation est que le noeud central a l' index 0
, et les enfants de noeud i
(triangles adjacents de la prochaine plus petite échelle) ont des indices 3i+1
, 3i+2
et 3i+3
.
Comment pouvons-nous nous déplacer dans ce graphique? Il y a jusqu'à six étapes naturelles que l'on peut entreprendre dans n'importe quel triangle:
- On peut toujours passer par le milieu d'une des arêtes à l'un des trois enfants du nœud actuel. Nous désignerons ces mouvements comme
N
,SW
etSE
. Par exemple , si nous sommes actuellement sur le nœud2
, ces conduirait à des noeuds7
,8
,9
respectivement. Les autres mouvements à travers les bords (vers les descendants indirects) sont interdits. - On peut aussi se déplacer dans l’un des trois coins, à condition qu’il ne touche pas le bord du triangle, jusqu’au parent direct ou à l’un des deux ancêtres indirects. Nous désignerons ces mouvements comme
S
,NE
etNW
. Par exemple, si nous sommes actuellement sur un nœud31
,S
conduirait à10
,NE
serait invalide etNW
conduirait à0
.
Le défi
Etant donné deux entiers non négatifs x
et y
, trouvez le chemin le plus court allant de x
à y
, en utilisant uniquement les six mouvements décrits ci-dessus. S'il existe plusieurs chemins les plus courts, indiquez l'un d'entre eux.
Notez que votre code devrait fonctionner pour plus que les 5 niveaux décrits dans le diagramme ci-dessus. Vous pouvez supposer que x, y < 1743392200
. Cela garantit qu'ils tiennent dans un entier signé 32 bits. Notez que cela correspond à 20 niveaux de l’arbre.
Votre code doit traiter toute entrée valide en moins de 5 secondes . Bien que cela exclue une recherche en force brute avec une largeur d'abord, cela devrait être une contrainte assez vague - mon implémentation de référence gère les entrées arbitraires pour la profondeur 1000 en une demi-seconde (c'est-à-dire des nombres à 480 chiffres pour les nœuds).
Vous pouvez écrire un programme ou une fonction en prenant l’entrée via STDIN (ou l’alternative la plus proche), un argument de ligne de commande ou une argumentation de fonction et en générant le résultat via STDOUT (ou l’alternative la plus proche), une valeur de retour de fonction ou un paramètre de fonction (out).
La sortie doit être une liste plate, sans ambiguïté des cordes N
, S
, NE
, NW
, SE
, SW
, à l' aide de tout séparateur raisonnable (espaces, virgules, retoursLigne, ","
...).
Les règles standard de code-golf s'appliquent.
Cas de test
Les premiers cas de test peuvent être élaborés à la main en utilisant le diagramme ci-dessus. Les autres veillent à ce que les réponses soient suffisamment efficaces. Pour ceux-là, il peut y avoir d'autres solutions de même longueur qui ne sont pas listées.
0 40 => N N N N
66 67 => S SW N N N
30 2 => NW NW -or- NE SW
93 2 => NE SW
120 61 => NW NW NW NW N SE SW N
1493682877 0 => S S NW NW
0 368460408 => SW SW N N SW SW SE SW SW N SE N N SW SW N SE SE
1371432130 1242824 => NW NW NE NW N SE SW SW SW SE SE SW N N N N SW
520174 1675046339 => NE NW NE NE SE SE SW SW N SE N SW N SW SE N N N N SE SE SW SW
312602548 940907702 => NE NW S SW N N SW SE SE SE SW SE N N SW SE SE SE SW
1238153746 1371016873 => NE NE NE SE N N SW N N SW N SE SE SW N SW N N SE N SE N
547211529 1386725128 => S S S NE NW N N SE N SW N SE SW SE SW N SE SE N SE SW SW N
1162261466 1743392199 => NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE