Это задача игры в гольф, в которой вам нужно разработать программу, которая действует как квин или квин, которая изменяет себя, чтобы проиллюстрировать машинное обучение.
Задний план
Существует базовая программа искусственного интеллекта под названием «игра в ящеров», которая описана здесь . Основная идея заключается в том, что программа при запуске в первый раз спрашивает:
Хорошо, пожалуйста, подумай
Это ящер?
Затем вы можете ответить либо:
да
В этом случае он говорит:
Хорошо. Это было так легко.
Или, если нет, он говорит:
Ой. Ну, тогда ты выиграл - О чем ты думал?
На что вы можете сказать:
собака
На что бы он сказал
Пожалуйста, дайте мне вопрос о собаке, чтобы я мог понять разницу между собакой и ящером
ты можешь ответить
Есть ли муравьи?
Было бы тогда спросить:
Какой ответ для собаки?
На что бы вы сказали
нет
И это сказал бы
Благодарность
В следующий раз, когда он запустится, он задаст вопрос выше и создаст двоичное дерево таких вопросов.
Соревнование
Достаточно фона. Задача состоит в том, чтобы написать самоизменяющуюся программу для ящеров. Правила следующие:
Вывод программы (как описано выше) должен быть
STDERR
. Окончательный ответ всегда будет «Хорошо. Это было так просто». или "Спасибо". После этого он должен вывести либо текущую версию программы, либо новую версию программы, в которую включен вопросSTDOUT
. Ни один ответ, написанный на языке, не поддерживающем записьSTDOUT
и /STDERR
или чтение,STDIN
не будет действительным.Другими словами, в UNIX вы можете вызвать программу следующим образом:
пример:
$ mylanguage myprogram > myprogram.1
[dialog goes here]
$ mylanguage myprogram1 > myprogram.2
[dialog goes here]
- Программа должна использовать точно указанные подсказки (поскольку сокращение подсказок не показывает навыка). Подсказки (без кавычек и где подставляется% s) следующие:
список:
"OK, please think of something"
"Is it %s?"
"Good. That was soooo easy."
"Oh. Well you win then -- What were you thinking of?"
"Please give me a question about %s, so I can tell the difference between %s and %s"
"What is the answer for %s?"
"Thanks"
Ожидая ответов «да / нет», ваша программа должна принять
y
илиyes
в любом случае «да»,n
илиno
в любом случае «нет». То, что вы делаете с несоответствующими входами, зависит от вас. Например, вы можете принять любой ответ, который начинается сy
илиY
как «да», а любой другой - как «нет».Вы можете предположить, что названия поставляемых вещей и вопросов состоят только из букв ASCII, цифр, пробелов, дефисов, вопросительных знаков, запятых, точек с запятой, двоеточий и точек с запятой, т.е. они соответствуют следующему регулярному выражению
^[-?,.;: a-zA-Z]+$
. Если вы можете справиться с чем-то большим (особенно с кавычками на выбранном вами языке), вы станете самодовольным, но не наберете лишних очков.Ваша программа не может прочитать или записать любой файл ( за исключением
STDIN
,STDOUT
иSTDERR
), или из сети; в частности, он не может ни читать, ни записывать свой собственный код с диска. Его состояние должно быть сохранено в самом коде программы.Когда программа запущена и правильно угадывает ответ, она должна работать точно как квинна, то есть она должна писать
STDOUT
точно в свой собственный код, без изменений.Когда программа запускается и неправильно угадывает ответ, она должна закодировать предоставленный новый вопрос и ответ в своем собственном коде и записать его
STDOUT
в своем собственном коде, чтобы она могла различать свое первоначальное предположение и предоставленный новый объект в дополнение к различению всех ранее заданных объектов.Вы должны быть в состоянии справиться с несколькими последовательными запусками программного обеспечения, чтобы оно узнало о многих объектах. Смотрите здесь примеры нескольких прогонов.
Пробеги испытаний приведены в ссылке в голове (очевидно , охватывающие только
STDIN
иSTDERR
диалог).Стандартные лазейки исключены.
Ответы:
Обыкновенный Лисп,
631576Пример сеанса
Назовите сценарий
pango1.lisp
и выполните его следующим образом (используя SBCL):Еще один раунд, добавив медведя:
Добавление ленивца (мы тестируем случай, когда ответ «нет»):
Тестирование последнего файла:
замечания
"Thanks"
, вот оно.(y or n)
, потому что я использую существующуюy-or-n-p
функцию. Я могу обновить ответ, чтобы удалить этот вывод, если это необходимо.*QUERY-IO*
поток, посвященный взаимодействию с пользователем, который я использую здесь. Стандартный вывод и взаимодействие с пользователем не мешают, что следует ИМХО по духу вопроса.SAVE-LISP-AND-DIE
будет лучшим подходом на практике.Сгенерированный выход
Вот последний сгенерированный скрипт:
Пояснения
Дерево решений может быть:
"a pangolin"
, которая представляет лист.(question if-true if-false)
гдеquestion
находится закрытый вопрос « да / нет» , в виде строки,if-true
иif-false
два возможных поддерева, связанных с вопросом.U
Функция ходит и возвращает в возможно модифицированное дерево. Каждый вопрос задается по очереди, начиная от корня до достижения листа, при взаимодействии с пользователем.Возвращаемое значение для промежуточного узла
(Q Y N)
-(Q (U Y) N)
(соответственно(Q Y (U N))
), если ответ на вопросQ
- да (соответственно нет ).Возвращаемым значением для листа является либо сам лист, если программа правильно угадала ответ, либо уточненное дерево, в котором лист заменяется вопросом и двумя возможными результатами в соответствии со значениями, взятыми у пользователя.
Эта часть была довольно простой. Для того, чтобы напечатать исходный код, мы используем переменные считывателя для создания самоссылочного кода.
Установив значениеХитрость при использовании*PRINT-CIRCLE*
true, мы избегаем бесконечной рекурсии во время симпатичной печати.WRITE
с:print-circle T
заключается в том, что функция также может возвращать значение в REPL в зависимости от того, является ли запись последней формой, и поэтому, если REPL не обрабатывает круговые структуры, как это определено стандартным значением по умолчанию:*PRINT-CIRCLE*
будет бесконечная рекурсия. Нам нужно только убедиться, что круговая структура не возвращается в REPL, поэтому в последней позиции LET присутствует NIL. Такой подход значительно уменьшает проблему.источник
(y or n)
не требуется, но я испытываю желание разрешить это, поскольку это улучшение.Python 2.7.6,
820728 байт(Может работать на разных версиях, но я не уверен)
Ну, он не такой короткий, как ответ на Common Lisp, но вот код!
источник
Python 3, 544 байта
Попробуйте онлайн!
Вопросы / ответы / ответы хранятся в массиве, где, если массив хранит три элемента (например
['Does it eat ants',['a pangolin'],['a dog']]
), тогда он получает ответ на вопрос и повторяет только содержимое второго или третьего элемента, в зависимости от ответа. Когда он попадает в массив только с одним элементом, он задает вопрос, и, поскольку у него есть весь исходный код в виде строки, он может использовать метод split-join для вставки расширения в массив для добавления новой ветви. ,Первоначально я написал это, не понимая требования к квине, поэтому перечитать вопрос и найти способ, с помощью которого я мог бы как выполнить код, так и использовать его в качестве строки, было трудно, но в конце концов я наткнулся на идею хорошего расширяемого формата quine:
источник
Python 3 , 497 байт
Очень похоже на «Безвредный» ответ для представления дерева. Он рекурсивно задает следующий вопрос, углубляясь в список, пока не останется только один ответ.
Безголовая версия (без кавычек)
источник