Défi
Vous disposez de deux chaînes de bits distinctes de la même longueur. (Par exemple, 000
et 111
.) Votre objectif est de trouver un chemin de l'un à l'autre tel que:
- A chaque étape, vous modifiez un seul bit (vous pouvez passer de
000
l'une001
,010
,100
). - Vous ne pouvez pas visiter la même chaîne de bits deux fois.
- Le chemin est le plus long possible, sous ces contraintes.
Par exemple, en allant de 000
à 111
, nous pouvons prendre le chemin
000, 001, 011, 010, 110, 100, 101, 111
qui visite toutes les chaînes de 8 bits de longueur 3, il doit donc être le plus long possible.
Règles
- Des échappatoires standard s'appliquent.
- Vous pouvez prendre l'entrée comme deux chaînes de zéros et de uns, ou comme deux tableaux de zéros et de uns, ou comme deux tableaux de valeurs booléennes.
- Vous ne pouvez pas prendre l'entrée comme deux entiers avec la bonne représentation binaire (écrit
000
et111
as0
et7
n'est pas valide). - Si vous le souhaitez, vous pouvez prendre la longueur des chaînes de bits en entrée.
- Votre programme est autorisé à générer le chemin en imprimant les chaînes de bits visitées une par une ou en renvoyant un tableau des chaînes de bits visitées (chacune au même format que l'entrée).
- Votre sortie doit inclure le début et la fin du chemin (qui sont vos entrées).
- C'est le code-golf , le code le plus court en octets gagne.
Exemples
0 1 -> 0, 1
10 01 -> 10, 00, 01 or 10, 11, 01
000 111 -> any of the following:
000, 100, 110, 010, 011, 001, 101, 111
000, 100, 101, 001, 011, 010, 110, 111
000, 010, 110, 100, 101, 001, 011, 111
000, 010, 011, 001, 101, 100, 110, 111
000, 001, 101, 100, 110, 010, 011, 111
000, 001, 011, 010, 110, 100, 101, 111
1001 1100 -> 1001, 0001, 0000, 0010, 0011, 0111, 0101, 0100, 0110, 1110, 1010, 1011, 1111, 1101, 1100 (other paths exist)
code-golf
binary
graph-theory
Misha Lavrov
la source
la source
Réponses:
Husk ,
27 2624 octetsForce brute, donc très lente. Essayez-le en ligne!
Explication
Husk lit naturellement de droite à gauche.
la source
Mathematica, 108 octets
Contribution:
Production:
la source
Mathematica, 175 octets
Belle première question!
Contribution
la source
Haskell ,
212207 octetsC'est probablement beaucoup trop long, mais cela fonctionne finalement maintenant. (Merci à @Lynn pour l' astuce du produit cartésien !) Merci @nimi pour -5 octets!
Essayez-le en ligne!
Explication:
la source
x<-mapM id$[1>0,1<0]<$b
[True,False]
? Si cela[False,True]
fonctionne également, vous pouvez utiliser[0>1..]
.Bool
estEnum
, et j'ai oublié que<$
est disponible ( d' abord essayé*>
qui n'est pas Prelude)!Mathematica
116114octetsAvec plusieurs octets enregistrés grâce à Misha Lavrov.
Entrée (8 dimensions)
Sortie (longueur = 254, après 1,82 seconde)
Tuples[{0,1},{l=Length@#}],{2}]
& génère les nombres 0 ... 8 sous forme de listes binaires.L'extérieur
Tuples...{2}
produit toutes les paires ordonnées de ces nombres binaires.Plus@@x
additionne chacune des paires, générant des triplets de 0, 1.Cases....Count[Plus@@x, 1]==1
renvoie toutes les sommes qui contiennent un seul 1. Celles-ci surviennent lorsque les deux nombres binaires d'origine sont connectés par un bord.Rules
relie les sommets du graphe, chaque sommet étant un nombre binaire.Graph
crée un graphique correspondant auxdits sommets et arêtes.FindPath
trouve jusqu'à 2 ^ n chemins reliant le sommet a au sommet b, les nombres donnés.Last
prend le plus long de ces chemins.Pour trois dimensions, le graphique peut être représenté dans un plan comme illustré ici:
Pour l'entrée,,
{0,0,0}, {1,1,1}
la sortie est la suivante:{{{0, 0, 0}, {0, 0, 1}, {0, 1, 1}, {0, 1, 0}, {1, 1, 0}, {1, 0, 0}, {1, 0, 1}, {1, 1, 1}}}
Ce chemin peut être trouvé dans le graphique ci-dessus.
Il peut également être conçu comme le chemin suivant dans 3 espaces, où chaque sommet correspond à un point
{x,y,z}
. {0,0,0} représente l'origine et {1,1,1} représente le point "opposé" dans un cube unitaire.Le chemin de solution correspond donc à une traversée d'arêtes le long du cube unitaire. Dans ce cas, le chemin est hamiltonien: il visite chaque sommet une fois (c'est-à-dire sans croisements et sans sommets omis).
la source
2^(l+2)
dans votre code?Haskell ,
141123 octetsUtilise des listes d'entiers. Essayez-le en ligne!
Explication
La fonction principale est
!
, et les fonctions auxiliaires sont#
etc
. Étant donné une liste de bits,c
donne toutes les façons possibles de retourner l'un d'eux, par exemple[0,1,1] -> [[1,1,1],[0,0,1],[0,1,0]]
.La fonction
#
prend une liste de listes (la "mémoire") et une liste (la "chaîne de bits initiale"). Il construit tous les chemins d'hypercube qui commencent par l'élément initial, ne contiennent que des chaînes de bits distinctes et ne marchent pas sur les chaînes de la mémoire.La fonction principale
!
relie tout cela ensemble. Une astuce que j'utilise ici estp*>x
( foisx
répétéeslength p
) au lieu delength p
. Étant donné que les répétitions plus longuesx
viennent plus tard dans l'ordre naturel des listes,maximum
choisit le chemin le plus long dans les deux cas, car les premières coordonnées des paires sont comparées avant les secondes.la source
Gelée ,
2527 octets+2 octets pour corriger un bug avec mon golf :( j'espère que je trouverai un moyen plus court cependant.
Un programme complet prenant les chaînes de bits en utilisant
1
et2
* comme listes. Les arguments sontfrom
etto
. Le programme imprime une liste de listes de la même chose.*
0
et1
peut être utilisé à la place au prix d'un octet (ajoutez’
entreL2ṗ
etŒ!ç€...
pour décrémenter).Essayez-le en ligne!
Comment?
mise à jour ...
la source
[1,1]
et[2,2]
une sortie de[[1, 1], [2, 1], [1, 2], [2, 2]]
quand je l'essaie en ligne, ce qui n'est pas un chemin valide.