Antecedentes
Hay dos personas, Bill y John. Uno de ellos es un caballero, que siempre dice la verdad, y el otro es un bribón, que siempre dice una mentira. No sabes quién es el caballero y quién es el bribón. Cada persona dice varias declaraciones sobre quién es el bribón y quién es el caballero. Con esta información, debe llegar a una conclusión sobre quién es el caballero y quién es el bribón.
El problema lógico de Knights and Knaves se basa en el álgebra de Booleen. Las palabras que una persona dice forman un problema de satisfacción de Booleen. Las declaraciones del bribón siempre deben ser falsas y las declaraciones del otro caballero siempre deben ser verdaderas.
John dice "Ambos soy un bribón y Bill es un bribón". Si John fuera el caballero, entonces esta afirmación sería falsa, por lo que no puede ser el caballero. Si él fuera el bribón y Bill el caballero, esta afirmación seguiría siendo falsa, incluso aunque la primera parte sea cierta. Entonces, John es el bribón.
El reto
Su desafío es escribir el programa más corto posible que tome una lista de declaraciones hechas por cada persona y descubra quién es el bribón y quién es el caballero. Hay muchos detalles que cubrir, por lo que este problema se describe en tres secciones.
Entrada
La entrada será de dos líneas seguidas de una nueva línea. Cada línea dará el nombre de uno de los caracteres, seguido de dos puntos, seguido de varias oraciones dichas por esa persona. Si una persona es el caballero, entonces todas sus oraciones serán verdaderas, y todas las oraciones del bribón serán falsas. La primera letra de una oración siempre estará en mayúscula y cada oración terminará con un punto. Aquí hay un ejemplo:
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.
Analizando
Cada oración consta de al menos una cláusula. Cada cláusula contiene una de varias cosas (espero que puedas entender mi notación):
both [clause] and [clause]
either [clause] or [clause]
neither [clause] nor [clause]
[I am | (other person's name) is] a [knight | knave]
Esto es ambiguo porque puede entenderse de manera similar a la notación polaca. Aquí hay un ejemplo de una oración:
Both I am a knight and neither Steve is a knave nor I am a knave.
La traducción al álgebra de Booleen es sencilla. Las declaraciones "ambas" son AND, las declaraciones "cualquiera" son XOR y las declaraciones "ninguno" son NOR.
(I am a knight) AND ((Steve is a knave) NOR (I am a knave))
Salida
La salida constará de dos líneas. Cada línea consiste en el nombre de una persona (en orden) y luego dice si él es el caballero o el bribón. Siempre habrá un caballero y un bribón. Aquí está la salida para el ejemplo anterior:
Joe is the knave.
Steve is the knight.
Si el problema no tiene solución (no puede saber quién es qué o no hay solución), entonces su programa puede hacer cualquier cosa, EXCEPTO producir un resultado válido.
Más ejemplos
Entrada
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.
Salida
Sir Lancelot is the knight.
Merlin is the knave.
Entrada
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.
Salida
David is the knave.
Patrick is the knight.
Entrada
Lizard: I am a knight.
Spock: I am a knave.
Una salida posible
Rock Paper Scissors
Reglas, Regulaciones y Notas
- Aplican reglas estándar de golf de código
- Su programa solo debe estar compuesto por ASCII imprimible
- Todas las entradas y salidas serán de STDIN y STDOUT
fuente
Respuestas:
Python, 491 caracteres
Funciona convirtiendo cada línea en una expresión de Python y luego igualando.
El bribón y el caballero se evalúan como 0 y 1. Para las dos personas, probamos ambas opciones.
Por ejemplo, se
Joe: Steve is a knave
convierteJoe==(Steve==knave)
. De esta manera, siJoe
es un bribón, el resultado es cierto solo si está mintiendo.Obtienes errores feos cuando es imposible o indeciso. Si es imposible,
r[0]
es un error de índice, porquer
está vacío. Si no se puede decidir, concatenarr[1:]
a una lista de cadenas causa problemas.fuente
Rubí, 352 caracteres.
La solución se hizo bastante larga, por lo que todavía podría haber algún lugar para el golf. Requiere que la entrada esté bien formada (como lo están todos los ejemplos anteriores, pero no intente nombrar a una persona "Ambos" ...).
fuente
Perl - 483 bytes
Similar a la solución Python. Reduce las oraciones al código Perl y luego
eval
las envía. Puede imprimir resultados casi válidos si la entrada es extraña, pero no imprime nada si es indecidible. La entrada bien formada funciona como se espera. Las oraciones se pasan en la línea de comando entre comillas y no se necesitan banderas especiales.fuente