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 розтяжки. Починаючи з пари спостережень:
- Рядки з лише 1 розтяжкою не сприяють зведенню головоломки, оскільки вони можуть ковзати в будь-яку сторону без зіткнень.
- Якщо всі рядки з двома розтяжками мають однаковий порядок
A
і B
, головоломка явно не переплітається. У цьому випадку всі A
осередки залишаються від усіх B
комірок, або навпаки, і при розсуванні цих двох частин немає зіткнень.
Єдиний складний випадок - це пазли, де у нас є рядки з 2-ма розтяжками різного порядку. Я збираюся показати, що таких задачок не існує за даними специфікаціями. Щоб показати це, давайте подивимось на часткову головоломку, яка має таку конфігурацію, де .
знаки підстановки:
.......
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.