fundo
Existem duas pessoas, Bill e John. Um deles é um cavaleiro, que sempre diz a verdade, e o outro é um cavalheiro, que sempre conta uma mentira. Você não sabe quem é o cavaleiro e quem é o escravo. Cada pessoa então diz várias declarações sobre quem é o escudeiro e quem é o cavaleiro. Usando essas informações, você deve chegar a uma conclusão sobre quem é o cavaleiro e quem é o escravo.
O problema lógico de Knights and Knaves é baseado na álgebra de Booleen. As palavras que uma pessoa diz formam um problema de satisfação de Booleen. As declarações do escudeiro devem sempre ser falsas e as declarações do outro cavaleiro devem sempre ser verdadeiras.
John diz: "Eu sou um canalha e Bill é um canalha". Se João fosse o cavaleiro, essa afirmação seria falsa, então ele não pode ser o cavaleiro. Se ele fosse o escudeiro e Bill o cavaleiro, essa afirmação ainda seria falsa, mesmo que a primeira parte fosse verdadeira. Então, John é o canalha.
O desafio
Seu desafio é escrever o programa mais curto possível, com uma lista de declarações feitas por cada pessoa e descobrir quem é o escravo e quem é o cavaleiro. Há muitos detalhes a serem abordados, portanto esse problema é descrito em três seções.
Entrada
A entrada terá duas linhas seguidas por uma nova linha. Cada linha fornecerá o nome de um dos caracteres, seguido de dois pontos, seguido de várias frases ditas por essa pessoa. Se uma pessoa é o cavaleiro, todas as suas sentenças serão verdadeiras, e todas as sentenças do valete serão falsas. A primeira letra de uma frase será sempre maiúscula e cada frase terminará com um ponto. Aqui está um exemplo:
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.
Análise
Cada sentença consiste em pelo menos uma cláusula. Cada cláusula contém uma de várias coisas (espero que você possa entender minha notação):
both [clause] and [clause]
either [clause] or [clause]
neither [clause] nor [clause]
[I am | (other person's name) is] a [knight | knave]
Isso é inequívoco, pois pode ser entendido de maneira semelhante à notação polonesa. Aqui está um exemplo de uma frase:
Both I am a knight and neither Steve is a knave nor I am a knave.
A tradução para a álgebra de Booleen é direta. As instruções "both" são ANDs, as instruções "or" são XORs e as instruções "nem" são NORs.
(I am a knight) AND ((Steve is a knave) NOR (I am a knave))
Resultado
A saída consistirá em duas linhas. Cada linha consiste no nome de uma pessoa (em ordem) e depois diz se ela é o cavaleiro ou o escudeiro. Sempre haverá um cavaleiro e um cavaleiro. Aqui está a saída para o exemplo acima:
Joe is the knave.
Steve is the knight.
Se o problema for insolúvel (ou você não pode dizer quem é o quê ou não há solução), seu programa pode fazer qualquer coisa, EXCETO produzir uma saída válida.
Mais exemplos
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.
Resultado
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.
Resultado
David is the knave.
Patrick is the knight.
Entrada
Lizard: I am a knight.
Spock: I am a knave.
Uma saída possível
Rock Paper Scissors
Regras, Regulamentos e Notas
- Aplicam-se regras de golfe de código padrão
- Seu programa deve ser composto apenas de ASCII imprimível
- Todas as entradas e saídas serão de STDIN e STDOUT