Ваша задача - написать интерпретатор RoboZZle. Если вы не знакомы с игрой, посмотрите видео на robozzle.com или прочтите мое описание ниже.
Робот живет на прямоугольной сетке из квадратов красного, зеленого, синего или черного цвета. Черные квадраты недоступны. Другие доступны, и некоторые из них содержат звезду. Цель состоит в том, чтобы собрать все звезды, не наступая на черные квадраты и не падая с карты. Робот занимает один квадрат и направлен в определенном направлении - влево, вправо, вверх или вниз. Он следует инструкциям, подобным сборке, сгруппированным в подпрограммы F1, F2, ..., F5. Инструкция - это пара предикатов («нет», «если на красном», «если на зеленом», «если на синем») и действия («идти вперед», «повернуть налево», «повернуть направо», «закрасить текущий квадрат красным», «закрасить его зеленым», «закрасить его синим», «ничего не делать», «вызвать F1», ..., «вызвать F5»). Вызовы подпрограмм используют стек и могут быть рекурсивными. Как и в обычном программировании, после того, как последняя инструкция подпрограммы завершена, выполнение продолжается с того места, где была вызвана подпрограмма. Выполнение начинается с первой инструкции F1 и продолжается до тех пор, пока робот не посетит все квадраты со звездами, или пока робот не выйдет на черный квадрат или за пределами карты, или пока не будет выполнено 1000 инструкций (неудачные предикаты и действия «ничего не делать») не в счет), или больше нет инструкций для выполнения (потеря стека).
Входы:
a
- матрица символов 12x16 (как обычно представлено на вашем языке, например, массив строк), которая кодирует карту -'#'
для недоступных (черных) квадратов,'*'
для квадратов со звездочкой,'.'
для остальныхc
- матрица символов 12x16, описывающая цвета доступных квадратов -'R'
(красный),'G'
(зеленый) или'B'
(синий). Недоступные квадраты будут представлены произвольной буквой из трех.y
иx
- строка и столбец робота на основе 0;a[y][x]
гарантированно будет'.'
d
- направление робот облицовочный:0 1 2 3
для правого, вниз, влево, вверх, то есть в направлении(y,x+1)
,(y+1,x)
,(y,x-1)
,(y-1,x)
f
- одиночная строка, связанные реализации F1 ... F5. Каждая реализация представляет собой (возможно, пустую) последовательность пар предикат-действие (не более 10 пар на подпрограмму), оканчивающихся на'|'
.предикаты:
'_'
нет,'r'
красный,'g'
зеленый,'b'
синийдействия:
'F'
идти вперед,'L'
повернуть налево,'R'
повернуть направо,'r'
покрасить красный,'g'
покрасить зеленый,'b'
покрасить синий,'1'
вызвать F1, ...,'5'
вызвать F5,'_'
ничего не делать
Вам не нужно называть входные данные, как указано выше, но их значения должны быть такими, как указано.
Вывод: 1
(или true
) если робот собирает все звезды в соответствии с правилами, 0
( false
) в противном случае.
Пример :
a=["################","################","##*....*...*#.##","##.####.#####.##","##.####.#####.##","##.####*...*#.##","##.########.####","##*........*#.##","################","################","################","################"]
c=["RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRBBBBRGGGGRRRR","RRBRRRRGRRRRRRRR","RRBRRRRGRRRRRRRR","RRBRRRRRGGGBRRRR","RRBRRRRRRRRGRRRR","RRRBBBBGGGGBRBRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR"]
y=2; x=6; d=2
// and then depending on "f":
f="_FrLg2_1|_FbLrR_2||||" // result:1
f="_FrRg2_1|_FbLrR_2||||" // result:0 (stepped on a black square)
f="_FrLrL_1|_FbLrR_2||||" // result:0 (1000-step limit exceeded)
f="_FrLg2__|________||||" // result:0 (stack underflow)
Другой пример , включающий «рисование» инструкций:
a=["#***************","#*###*###*###*##","#*###*###*###*##","***#***#***#***#","***#***#***#***#","*###*###*###*###","***#***#***#***#","***#***#***#***#","***#***#***#***#","*###*###*###*###","*.*#***#***#***#","***#***#***#***#"]
c=["RGGGGGGGGGGGGGGG","RBRRRGRRRGRRRGRR","RBRRRGRRRGRRRGRR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BRRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BGRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR"]
y=10; x=1; d=0
f="_2_R_R_1|_FgRgFgFg3rRr4b2_Fgb|_F_F_R|_2_L_r||"
// result:1
Чтобы создать свой собственный тест, перейдите к головоломке из списка на robozzle.com , попробуйте решить ее (или не решить), нажмите F12 в браузере и введите консоль JS:
r=robozzle;s=JSON.stringify;with(r.level)console.log('a='+s(Items)+'\nc='+s(Colors)+'\ny='+RobotRow+'\nx='+RobotCol+'\nd='+RobotDir+'\nf='+s(r.encodeSolution()))
и переформатировать результат для вашего языка.
Кратчайшие победы. Нет лазеек.
Ответы:
Пролог (SWI) , 574 байта
Попробуйте онлайн!
Это определяет предикат, который при вызове завершается успешно, если все звезды успешно собраны, и дает сбой в противном случае Предикат принимает аргументы как таковые
a+c+f+x^y^d.
.a
иc
должен быть списком строк в кавычках, в то время какf
должен быть строкой в двойных кавычках.объяснение
Эта программа содержит три предиката,
*/2
,^/2
, и+/2
. В*/2
предиката , которое определено на первой линии несет ответственность за часть обработки входного сигнала.^/2
Предикат рекурсивно вычисляет , как робот движется , шаг за шагом , и успешно , если робот легально собирает все звезды и не иначе.+/2
Предикат является основным предикатом программы и готовит материалы для^/2
предиката с некоторой помощью*/2
предиката. Обратите внимание, что каждый из этих предикатов технически принимает только два аргумента, но используя операторы и сопоставление с образцом, они могут вести себя так, как если бы у них было больше аргументов (я обсуждаю это явление более подробно здесь ).*/2
Этот предикат принимает два аргумента. Первый - это список списков кодов символов (именно так Prolog анализирует строки в кавычках в кавычках). Вторая - это ассоциативная карта от точек на карте 12x16 (обозначается как
X^Y
) до 32 плюс код символа, сохраненный в этой точке в списке списков кодов символов. 32 добавляется к каждому из кодов символов, так что для цветовой матрицы он преобразует цветные символы в верхнем регистре в цветные символы в нижнем регистре.То, как это происходит, генерирует список пар точек и кодов символов в этой точке, используя
findall/3
. Затем он используетсяlist_to_assoc/2
для создания соответствующей ассоциативной карты из точек в код символа в этой точке.findall/3
Предикат является встроенным принимает «шаблон» в качестве первого аргумента, цели в качестве второго аргумента и списка в качестве третьего аргумента. Предикат заполняет список всеми возможными значениями шаблона, которые приводят к достижению цели. Из-за приоритета оператора шаблон, который передается вfindall/3
in*/2
, анализируется как(X^Y)-D
.-
Оператор представляет собой пару из двух значений в Прологе поэтому шаблон представляет положение точки (X^Y
) в паре с кодом символа 32 плюс точки ( вD
). Обратите внимание, что^
используемый в представлении точки никоим образом не связан с^/2
предикатом.Давайте рассмотрим цель, которая передается
findall/3
предикату.Цель содержит три предиката, каждый из которых должен быть успешным для достижения цели.
nth0/3
Предикат , который используется дважды используется для получения значения в определенном индексе списка (0
в его названии указывает на то она равна нулю проиндексированы). При первом вызове в него сохраняетсяY
th-я строка символьной матрицы,O
тогда как при втором вызове сохраняетсяX
th-й символ в этой строкеC
. Последний предикатplus/3
завершается успешно, если его первые два аргумента суммируются с третьим аргументом. Это используется, чтобы сделать код символа в паре на 32 больше, чем код символа в матрице символов, который, как указано выше, превратит все заглавные буквы в строчные.Наконец,
findall/3
сохраняет всеX^Y-D
комбинации, которые приводят к достижению цели в списке, изL
которого построена ассоциативная карта.Продолжение следует...
источник
JavaScript (ES6),
298276264 байтаСохранено 8 байтов благодаря @ngn
Вводит как
(a,c,x,y,d,f)
, гдеa
иc
являются массивами массивов символов. Возвращает0
или1
.Контрольные примеры
Показать фрагмент кода
комментарии
источник
x+='2101'[d&3]-1,y+='1210'[d&3]-1
->d&=3,x+=(1-d)%2,y+=(2-d)%2
x
изменяется не более чем на 1, поэтому я думаю, что вы можете заменитьx&~15
наx&16
APL (Dyalog Classic) ,
236233 байта-3 спасибо Эрику Аутгольферу
Теперь, когда я отдал бонус, я публикую пример решения для моей собственной задачи. Здесь есть возможности для улучшения - не стесняйтесь копировать и играть в гольф дальше.
Попробуйте онлайн!
То же, что и выше, дополнено комментариями:
источник