CJam, 33 32 20 19 17 byte
Versi revisi, dengan dukungan besar-besaran dari @ Sp3000 dan @ MartinBüttner:
qN/_z]{:e`z,3<}/|
Cobalah online
Kontribusi
- @ Sp3000 menyarankan penyederhanaan kritis untuk algoritma asli saya.
- @ MartinBüttner menerapkan keterampilan bermain golfnya yang gila pada pendekatan yang direvisi, yang hampir pasti menghasilkan kode yang lebih pendek daripada yang akan saya pikirkan bahkan setelah mempertimbangkan penyederhanaan.
Algoritma dan Bukti
Berikut ini menjelaskan kriteria puzzle yang terpisah secara horizontal. Huruf vertikal dapat ditentukan dengan melihat kolom alih-alih baris, atau mentranspos matriks karakter dan melihat baris lagi.
Saya akan menggunakan istilah "stretch" untuk urutan maksimum dari huruf yang sama. Misalnya, baris berikut memiliki masing-masing 1, 2, dan 3 peregangan:
AAAAAAAA
BBBAAAAA
AABBBAAA
Saya juga akan menggunakan istilah "interlocked" untuk baris / puzzle yang tidak dapat digeser terpisah.
Pengamatan utama adalah bahwa teka-teki dapat meluncur terpisah jika dan hanya jika semua baris memiliki paling banyak 2 peregangan . Atau terbalik, itu saling terkait jika dan hanya jika ada baris dengan lebih dari 2 peregangan .
Berikut ini mungkin tidak memenuhi syarat sebagai bukti matematika yang ketat, tetapi saya percaya bahwa itu membuat penjelasan yang meyakinkan mengapa ini harus terjadi.
Sangat mudah untuk melihat bahwa teka-teki itu saling terkait jika memiliki baris lebih dari 2 peregangan. Melihat satu baris dengan 3 bagian:
BBBAAB
jelas bahwa itu mencegah puzzle dari meluncur terpisah karena A
peregangan terkunci di antara B
peregangan. Ini berarti bahwa baris saling bertautan, yang pada gilirannya membuat seluruh teka-teki saling bertautan.
Arah kebalikan dari bukti tidak begitu jelas. Kita perlu menunjukkan bahwa tidak ada teka-teki yang saling terkait di mana semua baris hanya memiliki 1 atau 2 peregangan. Dimulai dengan beberapa pengamatan:
- Baris dengan hanya 1 regangan tidak berkontribusi pada teka-teki yang saling terkait, karena mereka dapat meluncur ke arah mana pun tanpa tabrakan.
- Jika semua baris dengan 2 regangan memiliki urutan yang sama
A
dan B
, puzzle jelas tidak saling bertautan. Dalam hal ini, semua A
sel tersisa dari semua B
sel, atau sebaliknya, dan tidak ada tabrakan saat menggeser kedua bagian secara terpisah.
Satu-satunya kasus rumit adalah teka-teki di mana kita memiliki baris dengan 2 peregangan dengan urutan berbeda. Saya akan menunjukkan bahwa puzzle semacam itu tidak ada di bawah spesifikasi yang diberikan. Untuk menunjukkan ini, mari kita lihat sebagian puzzle yang memang memiliki konfigurasi ini, di mana .
wildcard:
.......
AAABBBB
.......
BBAAAAA
.......
Sekarang, spesifikasi mengatakan bahwa kedua sel A
dan B
hanya terhubung di semua teka-teki yang valid. Untuk membuat A
sel terhubung di sebagian puzzle di atas, kami memiliki dua opsi:
Kami melingkari salah satu peregangan B
, misalnya:
..AAAAAA
AAABBBBA
.......A
BBAAAAAA
........
Untuk melakukan ini, kita harus memperpanjang salah satu baris untuk memiliki 3 peregangan, jadi ini tidak akan pernah memberi kita teka-teki yang valid di mana semua baris memiliki paling banyak 2 peregangan.
Kami menghubungkan mereka di jalur langsung:
.......
AAABBBB
..A....
BBAAAAA
.......
The A
sel sekarang hanya terhubung, dan belum ada baris dengan lebih dari 2 membentang. Namun, B
sel - sel juga perlu dihubungkan secara sederhana. Jalur langsung sekarang diblokir oleh A
sel-sel yang terhubung , dan satu-satunya cara untuk menghubungkan B
sel - sel adalah untuk loop di sekitar salah satu peregangan A
sel. Ini mengarah kembali ke kasus 1, di mana kita tidak bisa melakukan itu tanpa membuat baris 3 peregangan.
Untuk menghitung peregangan, implementasinya menggunakan operator CJam RLE.
Penjelasan Kode
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.