Contexte
Il y a deux personnes, Bill et John. L'un d'eux est un chevalier, qui dit toujours la vérité, et l'autre est un chevalier, qui dit toujours un mensonge. Vous ne savez pas qui est le chevalier et qui est le chevalier. Chaque personne dit ensuite plusieurs déclarations sur qui est le chevalier et qui est le chevalier. En utilisant ces informations, vous devez arriver à une conclusion quant à savoir qui est le chevalier et qui est le chevalier.
Le problème de logique Knights and Knaves est basé sur l'algèbre de Booleen. Les mots qu'une personne dit forment un problème de satisfiabilité de Booleen. Les déclarations du chevalier doivent toujours être fausses et les déclarations de l'autre chevalier doivent toujours être vraies.
John dit "Je suis un mec et Bill est un mec". Si John était le chevalier, alors cette déclaration serait fausse, donc il ne peut pas être le chevalier. S'il était l'escroc et Bill le chevalier, cette affirmation serait toujours fausse, même si la première partie est vraie. Donc, John est le coquin.
Le défi
Votre défi est d'écrire le programme le plus court possible qui prendra une liste de déclarations faites par chaque personne et déterminera qui est le chevalier et qui est le chevalier. Il y a beaucoup de détails à couvrir, donc ce problème est décrit dans trois sections.
Contribution
La saisie se fera sur deux lignes suivies d'une nouvelle ligne. Chaque ligne donnera le nom d'un des caractères, suivi de deux points, suivi de plusieurs phrases prononcées par cette personne. Si une personne est le chevalier, alors toutes ses phrases seront vraies et toutes les phrases du chevalier seront fausses. La première lettre d'une phrase sera toujours en majuscule et chaque phrase se terminera par un point. Voici un exemple:
Joe: Both I am a knight and neither Steve is a knave nor I am a knave.
Steve: Joe is a knave. Either Joe is a knight or I am a knight.
Analyse
Chaque phrase comprend au moins une clause. Chaque clause contient une ou plusieurs choses (j'espère que vous pouvez comprendre ma notation):
both [clause] and [clause]
either [clause] or [clause]
neither [clause] nor [clause]
[I am | (other person's name) is] a [knight | knave]
Ceci est sans ambiguïté car il peut être compris d'une manière similaire à la notation polonaise. Voici un exemple de phrase:
Both I am a knight and neither Steve is a knave nor I am a knave.
La traduction en algèbre de Booleen est simple. Les instructions "Both" sont des ET, les instructions "Soit" sont des XOR et les instructions "Ni" sont des NOR.
(I am a knight) AND ((Steve is a knave) NOR (I am a knave))
Production
La sortie consistera en deux lignes. Chaque ligne se compose du nom d'une personne (dans l'ordre) et indique ensuite s'il est le chevalier ou le valet. Il y aura toujours un chevalier et un chevalier. Voici la sortie de l'exemple ci-dessus:
Joe is the knave.
Steve is the knight.
Si le problème est insoluble (soit vous ne pouvez pas dire qui est quoi, soit il n'y a pas de solution), votre programme peut faire quoi que ce soit SAUF pour produire une sortie valide.
Plus d'exemples
Contribution
Sir Lancelot: Either both I am a knight and Merlin is a knave or both I am a knave and Merlin is a knight.
Merlin: Either both I am a knight and Sir Lancelot is a knight or both I am a knave and Sir Lancelot is a knave.
Production
Sir Lancelot is the knight.
Merlin is the knave.
Contribution
David: Neither I am a knave nor Patrick is a knight. Either I am a knight or Patrick is a knave.
Patrick: Either I am a knight or both I am a knight and David is a knight.
Production
David is the knave.
Patrick is the knight.
Contribution
Lizard: I am a knight.
Spock: I am a knave.
Une sortie possible
Rock Paper Scissors
Règles, règlements et notes
- Les règles de golf à code standard s'appliquent
- Votre programme doit être composé uniquement d'ASCII imprimables
- Toutes les entrées et sorties proviendront de STDIN et STDOUT
la source
Réponses:
Python, 491 caractères
Fonctionne en convertissant chaque ligne en une expression Python et en l'évaluant.
L'esclave et le chevalier sont évalués comme 0 et 1. Pour les deux personnes, nous essayons les deux options.
Par exemple,
Joe: Steve is a knave
devientJoe==(Steve==knave)
. De cette façon, siJoe
est un coquin, le résultat n'est vrai que s'il ment.Vous obtenez des erreurs laides quand c'est impossible ou indécis. Si impossible,
r[0]
c'est une erreur d'index, carr
est vide. Si indécidable, la concaténationr[1:]
à une liste de chaînes provoque des problèmes.la source
Ruby, 352 caractères
La solution est devenue assez longue, il pourrait donc y avoir encore de la place pour le golf. Cela nécessite que l'entrée soit bien formée (comme le sont tous les exemples ci-dessus - mais n'essayez pas de nommer une personne "Les deux" ...).
la source
Perl - 483 octets
Similaire à la solution Python. Il réduit les phrases au code Perl puis les
eval
s. Il peut imprimer une sortie presque valide si l'entrée est bizarre mais n'imprime rien si elle est indécidable. Une entrée bien formée fonctionne comme prévu. Les phrases sont passées sur la ligne de commande entre guillemets et aucun indicateur spécial n'est nécessaire.la source