CJam, 33 32 20 19 17 байт
Пересмотренная версия с широкой поддержкой @ Sp3000 и @ MartinBüttner:
qN/_z]{:e`z,3<}/|
Попробуйте онлайн
взносы
- @ Sp3000 предложил критическое упрощение моего оригинального алгоритма.
- @ MartinBüttner применил свои безумные навыки игры в гольф к пересмотренному подходу, что почти наверняка привело к более короткому коду, чем я мог бы придумать даже после рассмотрения упрощения.
Алгоритм и Доказательство
Далее объясняются критерии для головоломки, раздвигающейся горизонтально. Вертикальный регистр может быть определен путем просмотра столбцов вместо строк или транспонирования матрицы символов и повторного просмотра строк.
Я буду использовать термин «растянуть» для максимальной последовательности тех же букв. Например, следующие строки имеют 1, 2 и 3 растяжения соответственно:
AAAAAAAA
BBBAAAAA
AABBBAAA
Я также буду использовать термин «заблокированный» для строки / головоломки, которые не могут раздвинуться.
Ключевое наблюдение заключается в том, что головоломка может раздвинуться, если и только если все ряды имеют максимум 2 растяжения . Или наоборот, он блокируется, если и только если есть какой-либо ряд с более чем 2 растяжками .
Следующее может не квалифицироваться как строгое математическое доказательство, но я считаю, что оно дает убедительное объяснение, почему это так.
Легко видеть, что головоломка блокируется, если она имеет ряды более 2-х отрезков. Глядя на ряд с 3-мя участками:
BBBAAB
Понятно, что это препятствует раздвижению головоломки, потому что A
натяжение заблокировано между B
отрезками. Это означает, что ряд заблокирован, что, в свою очередь, блокирует всю головоломку.
Противоположное направление доказательства не так очевидно. Нам нужно показать, что нет взаимосвязанных головоломок, где во всех рядах есть только 1 или 2 отрезка. Начиная с пары наблюдений:
- Строки с одним растяжением не способствуют блокировке головоломки, так как они могут скользить в любом направлении без каких-либо столкновений.
- Если все строки с 2-мя участками имеют одинаковый порядок
A
и B
, головоломка явно не блокируется. В этом случае все A
ячейки остаются от всех B
ячеек или наоборот, и при раздвижении двух частей нет столкновений.
Единственный сложный случай - это головоломки, в которых у нас есть ряды с двумя отрезками разного порядка. Я собираюсь показать, что таких головоломок не существует при данных спецификациях. Чтобы показать это, давайте посмотрим на частичную головоломку с такой конфигурацией, где .
используются шаблоны:
.......
AAABBBB
.......
BBAAAAA
.......
Теперь в спецификации говорится, что A
и B
ячейка, и ячейка просто связаны во всех действительных головоломках. Чтобы A
связать ячейки в частичной головоломке, представленной выше, у нас есть два варианта:
Мы зациклились на одном из отрезков B
, например:
..AAAAAA
AAABBBBA
.......A
BBAAAAAA
........
Чтобы сделать это, мы неизбежно расширяем один из рядов на 3 отрезка, так что это никогда не даст нам правильную головоломку, где все ряды имеют максимум 2 отрезка.
Мы соединяем их по прямому пути:
.......
AAABBBB
..A....
BBAAAAA
.......
Эти A
клетки теперь просто соединены, и до сих пор нет строки с более чем 2 -х участков. Тем не менее, B
клетки также должны быть просто связаны. Прямой путь теперь заблокирован соединенными A
ячейками, и единственный способ соединить B
ячейки - это обхватить один из участков A
ячейки. Это возвращает нас к случаю 1, где мы не можем сделать это, не создавая ряды из 3 отрезков.
Для подсчета растяжений в реализации используется оператор CJam RLE.
Объяснение кода
qN/ Get input and split at newlines.
_z Make a transposed copy.
] Wrap the original and transposed puzzle in an array so that we can
loop over the two.
{ Start of loop over original and transposed puzzle.
:e` Apply RLE to all rows.
z, Transpose the matrix with the RLE rows, and take the element count of the
result. Or in other words, take the column count. This will be the length
of the longest row after RLE.
3< Check the length for less than 3.
}/ End of loop over original and transposed puzzle.
| Or the results of the two.