Это код-гольф .
В этом задании мы будем писать программы / функции, которые решают головоломки « Рыцари и Кнавесы ».
Фон
Вы попадаете на остров ... и т. Д. ... каждый человек на острове, кроме вас, является либо рыцарем, либо мошенником .
Рыцари могут только делать правдивые заявления.
Knaves может только делать ложные заявления.
Я не хочу строго определять «утверждение», но мы скажем, что утверждение - это все, что является «истинным» или «ложным». Обратите внимание, что это исключает парадоксальные предложения.
В целях этого испытания вы встретите группы островитян; они сделают вам заявления.
Ваша задача - определить, кто такой рыцарь, а кто - мошенник.
Входные данные:
Вам будет предоставлена (в любом разумном формате) следующая информация:
Список присутствующих. Они будут названы заглавными буквами алфавита "AZ". Ограничение на количество людей, наложенное этим, не будет превышено.
Заявления, которые делает каждый человек. Ниже приведены важные подробности об этом.
Выход
Затем вы выведете (в любом разумном формате), что это за человек. Например, если были игроки A B C D
и A
это рыцарь, а остальные мошенники, вы можете вывести
A: 1
B: 0
C: 0
D: 0
Важные детали:
Прописные буквы алфавита AZ относятся к островитянам.
Символы
0
(ноль) и1
(один) относятся к «мошеннику» и «рыцарю» соответственно. (Вы можете использовать любые два других символа, отличных от AZ, если вы укажете)Каждый присутствующий островитянин может делать любое естественное количество заявлений или может ничего не говорить.
Нормальные логические операторы могут использоваться в выражениях ( IS *, AND, OR, NOT ). Кроме того, могут быть использованы законы и условия Де Моргана . Ниже приведены примеры того, как они могут быть представлены в устной головоломке, а затем, как они могут быть введены в вашу программу.
(* на более техническом примечании. Оператор «IS» действительно используется как сдерживание (что не является логическим оператором). Когда я говорю «А - это Рыцарь», я действительно имею в виду «А - член набора Рыцари ". Истинным оператором будет« ϵ ». Для простоты мы будем использовать« = ».)
Я использую следующее (вы можете использовать что угодно, если это разумно и последовательно):
^
Иv
ИЛИ=
ЯВЛЯЕТСЯ~
НЕ=>
ПОДРАЗУМЕВАЕТX:
Человек X утверждает, что ...
Человек Z может сделать любую комбинацию любого из следующих типов утверждений:
Человек Z говорит, что ...
Человек А - Рыцарь.
Z: A = 1
Человек Q - мошенник.
Z: Q = 0
Я рыцарь.
Z: Z = 1
Человек А - Рыцарь ИЛИ Человек Б - Рыцарь.
Z: ( A = 1 ) v ( B = 1)
Человек С - рыцарь, а я - мошенник.
Z: ( C = 1 ) ^ ( Z = 0 )
Человек R не рыцарь.
Z: ~( R = 1 )
Кроме того, вход может также использовать законы де Моргана
Неверно, что и человек А, и человек Б являются клаве
Z: ~( ( A = 0 ) ^ ( B = 0 ) )
Ложно, что либо человек А, либо человек Б - рыцарь
Z: ~( ( A = 1 ) v ( B = 1) )
Наконец, можно использовать условные выражения и их отрицания
Если я рыцарь, то человек Б - мошенник
Z: ( Z = 1 ) => ( B = 0 )
Неверно, что если человек B - рыцарь, то человек C - мошенник.
Z: ~( ( B = 1 ) => ( C = 0 ) )
Примечания об условных
Проверьте Википедию для получения дополнительной информации.
Условное утверждение принимает форму p => q , где p и q сами являются утверждениями. р является «предшественником», а q - «последующим». Вот некоторая полезная информация
Отрицание условия выглядит так: ~ (p => q) эквивалентно p ^ ~ q
Ложная предпосылка подразумевает что угодно. То есть: если p ложно, то любое утверждение p => q верно, независимо от того, что есть q . Например: «если 2 + 2 = 5, то я человек-паук» - это верное утверждение.
Несколько простых тестовых случаев
Эти случаи приведены следующим образом (1) как мы поставили бы проблему в речи (2) как мы могли бы поставить ее на компьютер (3) правильный вывод, который мог бы дать компьютер.
Человек А и Человек Б подходят к вам на дороге и делают следующие заявления:
A: B мошенник или я рыцарь.
Б: А это рыцарь.
Ответ:
B - рыцарь, а A - рыцарь.
Входные данные:
A B # Cast of Characters
A: ( B = 0 ) v ( A = 1)
B: A = 1
Выход:
A = 1 B = 1
Люди A, B и F подходят к вам на дороге и делают следующие заявления:
A: Если я рыцарь, то B - мошенник.
B: Если это правда, то F тоже мошенник.
Ответ:
A - Рыцарь, B - Мошенник, F - Рыцарь.
вход
A B F
A: ( A = 1 ) => ( B = 0 )
B: ( A = 1 ) => ( F = 0 )
Выход:
A = 1 B = 0 F = 1
Q, X и W подходят к вам на дороге и делают следующие заявления:
W: Это неправда, что оба Q и X являются рыцарями.
Q: Это правда.
X: Если то, что говорит W, верно, то то, что говорит Q, неверно.
Ответ:
W и Q - рыцари. Х мошенник.
вход
Q X W
W: ~( ( Q = 1 ) ^ ( X = 1 ) )
Q: W = 1
X: ( W = 1 ) => ( Q = 0 )
Выход
W = 1 Q = 1 X = 0
Существует аналогичная проблема от 3-х лет назад, которая фокусируется на разборе и не содержит условных выражений или де Моргана. И поэтому, я бы сказал, достаточно отличается по своей направленности и реализации, чтобы это не было обманом.
Этот вызов был кратко закрыт как обман. С тех пор он был вновь открыт.
Я утверждаю, что эта проблема, во-первых, отличается в фокусе. Другая проблема фокусируется на разборе английского, это не так. Во-вторых, он использует только И и ИЛИ, тогда как он использует условные выражения и позволяет решать гораздо больше головоломок. В конце концов, вопрос заключается в том, можно ли тривиально заменить этот ответ на этот вызов или нет, и я считаю, что включение условных и условных отрицаний добавляет достаточную сложность, чтобы потребовались более надежные изменения, чтобы чтобы соответствовать этому вызову.
(B=1)=>(C=0)
?~((B=1)=>(C=0))
или(B=1)=>(C=1)
или что-то еще?OR
, это может бытьA:1 B:1
илиA:1 B:0
потому, что BB=1
может быть ложным, в то время как A все еще будет истинным.(B=1)^(C=1)
как в соответствии с тем, как обычно обрабатываются условные выраженияОтветы:
Python 3,
450342307 байтРедактировать: оказывается, я забыл импорт ...
Мое первое решение использует гибкое именование для запросов
Вы можете позвонить выше с
Следующий здесь использует тот же формат запросов, что и в OP, в нем также нет некоторых модификаций, которые я сделал в первом. Это 417 байт, потому что он конвертирует между двумя форматами.
И это можно назвать по:
Они оба возвращаются
Ungolfed Объяснение:
Кроме того, второе решение требует 3,5 (не 3,4) из-за использования PEP 448
источник
Mathematica, 80 байт
объяснение
Функция
F
принимает два аргумента,c
список имен всех персонажей,s
это список утверждений, каждое из которых состоит из двух частей - кто что говорит.Например, есть три символа, Q, X и W.
И они говорят,
где
True
иFalse
означает рыцари и кнавесы соответственно. потомдаст
{{q->True, x->False, w->True}}
, что означает, что есть только одно решение, что Q и W - рыцари, а X - мошенник. Если существует более одного решения, результат будет выглядеть{{...},{...},...}
Алгоритм очень прост.
{True,False}~Tuples~Length@c
дает все возможные комбинации рыцарей и Knaves среди персонажей. ЗатемThread[c->#]&/@
создайте массив правил на основе этих комбинаций. В случае двух символов A и B массив будетПодставляя операторы с одной строкой этих правил, мы получим массив, похожий на
В первом столбце этого массива указаны имена выступающих, а во втором столбце указано, являются ли их утверждения истинными или ложными. Для правильного решения требуется соответствие личности докладчиков и их заявлений. Приведенный выше массив означает, что эта комбинация не является решением, поскольку второй оратор, Рыцарь, делает неверное утверждение.
выполняет замены и выбирает те комбинации, которые удовлетворяют условию.
источник
Руби, 128
Это тот же алгоритм, что и у всех остальных, попробуйте все возможные комбинации мошенников и рыцарей и посмотрите, какие палки. У меня есть другой, над которым я работаю, но я думаю, что это будет дольше (хотя и более интересно).
Входные данные оператора должны быть:
&
И|
ИЛИ==
ЯВЛЯЕТСЯ!
НЕ>
ПОДРАЗУМЕВАЕТX:
Человек X утверждает, что ...Я также требую, чтобы каждое утверждение и под-утверждение были в скобках. Единственная проблема с этой версией состоит в том, что она проходит не более 2 ^ 26 итераций, а если они не все мошенники, по крайней мере 2 ^ (26-n) итераций ! Чтобы представить это в перспективе, это означает, что если есть два человека, и по крайней мере один не мошенник, потребуется минимум 16 777 216 итераций !
Чтобы ограничить это, я отправляю следующее в 168 байтах. Sub в
26
течение#{o.size}
сократить его обратно до 161.Но если я могу вместо этого использовать массив людей и карту утверждений, например:
Тогда я получаю это до 128.
источник