Фон
В Bejeweled и подобных играх игрок должен поменять местами любые два смежных камня (без диагоналей) в сетке камней 8x8, чтобы соответствовать трем одинаковым цветам подряд. Драгоценные камни могут быть сопоставлены по горизонтали или вертикали. Игровой процесс продолжается до тех пор, пока не будет выполнено ни одного хода, что приведет к трем подряд, после чего игра заканчивается.
задача
Цель состоит в том, чтобы написать программу, которая определяет, не закончена ли игра Bejeweled. Другими словами, он должен проверить, есть ли возможный ход, который делает по крайней мере три подряд. Может быть более трех драгоценных камней подряд, и это все еще действительный ход.
вход
Ваша программа должна принимать через стандартный ввод 8x8 представление сетки Bejeweled. Каждый из семи цветов драгоценных камней будет представлен цифрой от 1 до 7. Каждая строка будет содержать одну строку, и будет введено 8 строк, каждая из которых состоит из 8 цифр. Смотрите примеры. Вы можете предположить, что входные данные всегда будут следовать этому формату и никогда не будут содержать три подряд.
Выход
Затем программа должна вывести (на стандартный вывод) yes
или в no
зависимости от того, существует или нет хотя бы одно допустимое движение, которое привело бы к трем или более драгоценным камням в строке. Ваша программа не должна выводить ничего, кроме одного экземпляра yes
или no
.
правила
Ваша программа не должна использовать какие-либо внешние файлы или ресурсы, аргументы командной строки или требовать определенного имени файла. Программа с наименьшим количеством байтов в исходном коде выигрывает.
Примеры
Входные данные:
12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656
Выход: yes
Входные данные:
35261546
76421754
15743271
62135642
35617653
64565476
54427254
15635465
Выход: no
См . Ответ MT0 ниже для дополнительных тестовых случаев.
Ответы:
Исходное решение: JavaScript -
261255228227179153 символовПредполагая, что проверяемая строка находится в переменной
s
(чтобы сделать ее функцией,f
добавьтеf=s=>
ее в начало кода или, в противном случае, получите ввод из приглашения, а затем заменитеs
наprompt()
).Выходы есть на консоль.
3- е решение: JavaScript (ECMAScript 6) - 178 символов
Я взял второе решение ниже (которое использует регулярные выражения для проверки символов в определенных конфигурациях) и переработал его, чтобы просто проверить строку на наличие идентичных символов в тех же конфигурациях без использования регулярных выражений.
Строка Base-36
"2313ab1b8a2a78188h9haj9j8iaiir9r"
дает пары смещений для проверки - то есть в23
результате пары проверяется, идентичен ли i- й символ (i + 2) -ому символу и (i + 3) -ому символу (эквивалент регулярного выражения).(.).\1\1
- с некоторыми дополнительными проверками, чтобы убедиться, что неидентичный символ не является новой строкой).2- е решение: JavaScript (ECMAScript 6) - 204 символа
Создает несколько регулярных выражений (подробнее см. Ниже) с использованием пар значений, взятых из строки Base-18,
10907160789879h8
и принимаетOR
все тесты. Чтобы еще больше его уменьшить, вы можете заметить, что регулярные выражения идут парами, где одно является «обратным» другому (игнорируя регулярные выражения для 3-в-ряд по горизонтали и вертикали, так как OP заявляет, что они никогда не будут присутствовать - если вы хотите добавить эти тесты обратно в дополнение к0088
строке Base-18).объяснение
Начните с 16 регулярных выражений, охватывающих все возможные конфигурации допустимых ходов:
( Примечание: регулярные выражения для 3-х в ряд по горизонтали (0- й ) и вертикальной (часть 9- го ) не имеют значения, так как OP заявляет, что входные данные, соответствующие этим, никогда не будут присутствовать. )
Тестирование каждого из этих входных данных определит, можно ли найти действительный ход этой конфигурации.
Тем не менее, регулярные выражения могут быть объединены, чтобы получить эти 6:
Затем они могут быть объединены в одно регулярное выражение:
Который просто должен быть проверен на входе.
Тестовые случаи
Некоторые тестовые случаи, которые другие люди могут найти полезными (не соответствует формату ввода, в котором используются только цифры 1-7, но это легко исправить и это только сетка 8x4 - так как это минимум, необходимый для проверки всех допустимых входных данных ).
В формате карты из входной строки, с которой из 16 регулярных выражений выше соответствует.
Редактировать 1
Заменить
\d
s на.
- сохраняет 6 символов.Редактировать 2
Заменить
(?:.|\n)
с[\s\S]
и удалены дополнительными не-захватом групп и обновленными обратными ссылками (в соответствии с рекомендацией м-Бюттнером ) и добавленными в да / нет выхода.Редактировать 3
Редактировать 4
Добавлено другое (более короткое) решение и еще два несоответствующих теста.
Редактировать 5
Редактировать 6
источник
?'yes':'no'
в свой счет символов для справедливости, потому что это в требованиях, и все остальные используют его..
соответствия любому символу, включая перевод строки? В Perl объединенное регулярное выражение - это всего лишь 129-байтовая строка (которая, будучи ленивой, я скомпилировал с помощью Regexp :: Assemble ), поэтому вся программа на Perl составляет около 150 байтов..{8}|.{9}
на.{8,9}
и.{7}|.{8}
с.{7,8}
Python 383
Всего одна * строка Python!
* Ну, с точкой с запятой, но это все еще нетривиально в Python (однострочники Python - это весело! )
источник
Node.js - Наивное решение - 905 байт
Ну, пока нет ответов, поэтому я выложу очень наивное решение в Node.js
Он проходит каждый возможный ход и затем проверяет получившуюся доску, чтобы увидеть, есть ли 3 подряд.
Гольф (с компилятором google closure) (некоторые хакерские штуки там, такие как! 0 и! 1; я даже не уверен, что он сделал с моим свопом XOR)
Обратите внимание, что я написал все это на своем мобильном телефоне, и у меня нет времени, чтобы проверить это или что-то еще. Прокомментируйте, если вы обнаружите какие-либо ошибки, я проверю это позже.
Предварительно гольф-версия для чтения человеком
источник
Perl,
11496959392878685 байтВключает + для
-a0p
Запустите с помощью ввода на STDIN:
bejeweled.pl
:Это объединяет горизонтальное регулярное выражение в одном направлении с вращением
Объяснение:
В этом решении я буду многократно вращаться и выполнять следующие 4 теста:
Где
\C
"любой символ" (в отличие от.
этого включает перевод строки). За исключением того, что\C
это устарело и приводит к предупреждениям, поэтому я использую\H
(не горизонтальное пространство) вместо этого, который достаточно хорош, чтобы захватить все цифры и новую строку.После 4 оборотов пройдут все 16 необходимых тестов.
источник
Python3, 314B
Измените 8, 5 в строке 6 и 8 в строке 9 для обработки произвольно больших входных размеров; Также не имеет значения, что представляет собой каждое значение, поэтому вы можете указать его:
и он вернется
yes
.Аннотации
источник
GNU sed 255 + 2 = 257B
Я думал, что это будет не так хорошо, как Python, но сейчас: - / У меня сегодня не было доступа к интернету, поэтому я занялся решением этой проблемы в sed :). Должен вызываться с флагом -r, т.е.
sed -rf command.sed < input
я добавил 2 к своему счету.Как это устроено:
источник
Рубин, 201 байт
Я был разочарован тем, что не смог найти решения этой большой проблемы, в котором не использовалось бы регулярное выражение или грубая сила (хотя это здорово), поэтому я написал одно. Требуется ввод на STDIN.
Ядро побитового арифметического алгоритма получено из этого фантастического ответа @leander на Game Stack Exchange .
Рубиновая лямбда, 181 байт
Здесь это как лямбда, которая берет строку и возвращает
true
илиfalse
:Смотрите его на repl.it: https://repl.it/ColJ/2
Ungolfed & объяснение
Код перебирает цифры от «1» до «9». Каждая итерация имеет два отдельных шага:
Первым шагом является преобразование платы, которое вы можете увидеть в
s.scan(n)
блоке в не раскрашенном коде. Он преобразует доску в массив из 8 целых чисел, по одному для каждой строки, обрабатывая совпадающие цифры как 1 и все остальные как 0 в двоичной строке. Например, взять строку12231123
. В первой итерации она становится двоичной строкой10001100
(все 1 становятся-эр, остаются-1, а все остальные цифры становятся 0), что является десятичным числом 140. Во второй итерации эта же строка становится01100010
(все 2 становятся 2 и все остальные цифры становятся 0) или десятичными 98.Он одновременно выполняет второе преобразование, которое совпадает с первым, но с поворотом доски на 90 градусов. Это позволяет нам использовать ту же логику для горизонтальных совпадений, что и вертикальные. Для простоты он объединяет две платы в одну длинную с нулем в начале, серединой (для разделения двух плат) и концом для заполнения.
Второй шаг - поиск возможных совпадений, которые вы можете увидеть в
each_cons(3).any?
блоке. Преобразованные строки (которые теперь являются 8-разрядными целыми числами) проверяются в (перекрывающихся) группах по три строки ( x , y , z ) с использованием побитовой арифметики. Каждая группа проверяется, чтобы увидеть, можно ли найти совпадение в строке y , либо сместив фигуру в строке y, либо сместив фигуру в y из x или z . Поскольку перед и после строк с исходной и повернутой досками есть нулевой «ряд», нам не нужно проверять, находимся ли мы в первом или последнем ряду доски.Если совпадений не найдено, оно продолжается до следующей итерации.
источник