Edit: ce puzzle est également connu sous le nom de "L'énigme d'Einstein"
Le propriétaire du zèbre (vous pouvez essayer la version en ligne ici ) est un exemple d'énigmes classiques et je parie que la plupart des utilisateurs de Stack Overflow peuvent le résoudre avec un stylo et du papier. Mais à quoi ressemblerait une solution programmatique?
Sur la base des indices énumérés ci-dessous ...
- Il y a cinq maisons.
- Chaque maison a sa propre couleur unique.
- Tous les propriétaires sont de nationalités différentes.
- Ils ont tous des animaux différents.
- Ils boivent tous des boissons différentes.
- Ils fument tous des cigarettes différentes.
- L'Anglais habite la maison rouge.
- Le Suédois a un chien.
- Le Danois boit du thé.
- La maison verte est sur le côté gauche de la maison blanche.
- Ils boivent du café dans la serre.
- L'homme qui fume le Pall Mall a des oiseaux.
- Dans la maison jaune, ils fument Dunhill.
- Dans la maison du milieu, ils boivent du lait.
- Le Norvégien vit dans la première maison.
- L'homme qui fume Blend vit dans la maison à côté de la maison avec des chats.
- Dans la maison à côté de la maison où ils ont un cheval, ils fument du Dunhill.
- L'homme qui fume Blue Master boit de la bière.
- L'Allemand fume Prince.
- Le Norvégien habite à côté de la maison bleue.
- Ils boivent de l'eau dans la maison voisine de la maison où ils fument Blend.
... à qui appartient le Zebra?
Réponses:
Voici une solution en Python basée sur la programmation par contraintes:
Production:
Il faut 0,6 seconde (CPU 1,5 GHz) pour trouver la solution.
La réponse est "L'Allemand possède le zèbre".
Pour installer le
constraint
module viapip
: pip install python-constraintPour installer manuellement:
Télécharger:
$ wget https://pypi.python.org/packages/source/p/python-constraint/python-constraint-1.2.tar.bz2#md5=d58de49c85992493db53fcb59b9a0a45
extrait (Linux / Mac / BSD):
$ bzip2 -cd python-constraint-1.2.tar.bz2 | tar xvf -
extrait (Windows, avec 7zip ):
> 7z e python-constraint-1.2.tar.bz2
> 7z e python-constraint-1.2.tar
installer:
$ cd python-constraint-1.2
$ python setup.py installer
la source
pip install python-constraint
? Je l'ai fait il y a un instant et cela semble donner le résultat attendu.Dans Prolog, nous pouvons instancier le domaine simplement en sélectionnant des éléments à partir de celui-ci :) (en faisant des choix mutuellement exclusifs , par souci d'efficacité). En utilisant SWI-Prolog,
Fonctionne assez instantanément:
la source
Une affiche a déjà mentionné que Prolog est une solution potentielle. C'est vrai et c'est la solution que j'utiliserais. En termes plus généraux, c'est un problème parfait pour un système d'inférence automatisé. Prolog est un langage de programmation logique (et un interpréteur associé) qui forme un tel système. Il permet essentiellement de conclure des faits à partir de déclarations faites en utilisant la logique du premier ordre . FOL est fondamentalement une forme plus avancée de logique propositionnelle. Si vous décidez que vous ne souhaitez pas utiliser Prolog, vous pouvez utiliser un système similaire de votre propre création en utilisant une technique telle que modus ponens pour tirer les conclusions.
Vous devrez, bien sûr, ajouter quelques règles sur les zèbres, car cela n'est mentionné nulle part ... Je crois que l'intention est que vous puissiez comprendre les 4 autres animaux de compagnie et ainsi en déduire que le dernier est le zèbre? Vous voudrez ajouter des règles qui stipulent qu'un zèbre est l'un des animaux de compagnie, et chaque maison ne peut avoir qu'un seul animal. Obtenir ce type de connaissances «de bon sens» dans un système d'inférence est le principal obstacle à l'utilisation de la technique comme une véritable IA. Il existe des projets de recherche, tels que Cyc, qui tentent de donner une telle connaissance commune par la force brute. Ils ont rencontré un succès intéressant.
la source
Compatible SWI-Prolog:
Chez l'interprète:
la source
Voici comment je procéderais. D'abord, je générerais tous les n-tuples ordonnés
5 ^ 6 d'entre eux, 15625, facilement gérables. Ensuite, je filtrerais les conditions booléennes simples. il y en a dix, et chacun de ceux que vous vous attendez à filtrer 8/25 des conditions (1/25 des conditions contiennent un Suédois avec un chien, 16/25 contiennent un non-Suédois avec un non-chien) . Bien sûr, ils ne sont pas indépendants, mais après avoir filtré ceux-ci, il ne devrait plus en rester beaucoup.
Après cela, vous avez un joli problème de graphique. Créez un graphique avec chaque nœud représentant l'un des n-uplets restants. Ajoutez des arêtes au graphique si les deux extrémités contiennent des doublons dans une position de n-uplets ou enfreignent les contraintes de «position» (il y en a cinq). De là, vous êtes presque à la maison, recherchez dans le graphique un ensemble indépendant de cinq nœuds (sans aucun des nœuds connectés par des arêtes). S'il n'y en a pas trop, vous pouvez simplement générer de manière exhaustive tous les 5-tuples de n-tuples et les filtrer à nouveau.
Cela pourrait être un bon candidat pour le code golf. Quelqu'un peut probablement le résoudre en une seule ligne avec quelque chose comme haskell :)
après coup: la passe de filtre initiale peut également éliminer les informations des contraintes de position. Pas grand chose (1/25), mais toujours significatif.
la source
Une autre solution Python, cette fois en utilisant PyKE (Python Knowledge Engine) de Python. Certes, c'est plus verbeux que d'utiliser le module «contrainte» de Python dans la solution de @JFSebastian, mais il fournit une comparaison intéressante pour quiconque cherche dans un moteur de connaissances brutes pour ce type de problème.
indices.kfb
relations.krb
driver.py (en fait plus grand, mais c'est l'essence même)
Exemple de sortie:
Source: https://github.com/DreadPirateShawn/pyke-who-owns-zebra
la source
Voici un extrait de la solution complète utilisant NSolver , publiée sur Einstein's Riddle en C # :
la source
Voici une solution simple en CLP (FD) (voir aussi clpfd):
L'exécuter, produit:
la source
neighbor(X,Y) :- abs(X-Y) #= 1.
Dans PAIP (chapitre 11), Norvig résout le puzzle du zèbre en utilisant un Prolog intégré dans Lisp .
la source
Solution ES6 (Javascript)
Avec beaucoup de générateurs ES6 et un peu de lodash . Vous aurez besoin de Babel pour exécuter ceci.
Résultat:
Le temps d'exécution est d'environ 2,5 secondes pour moi, mais cela peut être beaucoup amélioré en modifiant l'ordre des règles. J'ai décidé de conserver la commande d'origine pour plus de clarté.
Merci, c'était un défi sympa!
la source
C'est vraiment un problème de résolution de contraintes. Vous pouvez le faire avec un type généralisé de propagation de contraintes dans les langages de programmation logique. Nous avons une démo spécifiquement pour le problème Zebra dans le système ALE (attribut logic engine):
http://www.cs.toronto.edu/~gpenn/ale.html
Voici le lien vers le codage d'un puzzle Zebra simplifié:
http://www.cs.toronto.edu/~gpenn/ale/files/grammars/baby.pl
Faire cela efficacement est une autre affaire.
la source
Le moyen le plus simple de résoudre de tels problèmes par programme est d'utiliser des boucles imbriquées sur toutes les permutations et de vérifier si le résultat satisfait les prédicats de la question. De nombreux prédicats peuvent être hissés de la boucle interne vers les boucles externes afin de réduire considérablement la complexité de calcul jusqu'à ce que la réponse puisse être calculée dans un temps raisonnable.
Voici une solution F # simple dérivée d'un article du journal F # :
La sortie obtenue en 9ms est:
la source
L'exemple Microsoft Solver Foundation de: https://msdn.microsoft.com/en-us/library/ff525831%28v=vs.93%29.aspx?f=255&MSPPError=-2147217396
la source
Ceci est une solution MiniZinc au puzzle de zèbre tel que défini dans Wikipedia:
Solution:
la source