CJam, 33 32 20 19 17 byte
Versione rivista, con il massiccio supporto di @ Sp3000 e @ MartinBüttner:
qN/_z]{:e`z,3<}/|
Provalo online
contributi
- @ Sp3000 ha suggerito una semplificazione fondamentale per il mio algoritmo originale.
- @ MartinBüttner ha applicato le sue pazze abilità di golf all'approccio rivisto, che quasi sicuramente ha prodotto un codice più breve di quello che avrei escogitato anche dopo aver considerato la semplificazione.
Algoritmo e prova
Di seguito vengono spiegati i criteri per il puzzle che si separa orizzontalmente. Il caso verticale può essere determinato guardando le colonne anziché le righe, oppure trasponendo la matrice di caratteri e guardando di nuovo le righe.
Userò il termine "tratto" per una sequenza massima delle stesse lettere. Ad esempio, le seguenti righe hanno rispettivamente 1, 2 e 3 allungamenti:
AAAAAAAA
BBBAAAAA
AABBBAAA
Userò anche il termine "interbloccato" per una riga / puzzle che non può separarsi.
L'osservazione chiave è che il puzzle può scivolare via se e solo se tutte le file hanno al massimo 2 tratti . O invertito, è bloccato se e solo se c'è una fila con più di 2 tratti .
Quanto segue potrebbe non qualificarsi come una rigorosa dimostrazione matematica, ma credo che sia una spiegazione convincente del perché questo debba essere il caso.
È facile vedere che il puzzle è interbloccato se ha file di più di 2 tratti. Guardando una fila con 3 tratti:
BBBAAB
è chiaro che impedisce al puzzle di scivolare via perché il A
tratto è bloccato tra i B
tratti. Ciò significa che la riga è interbloccata, il che a sua volta rende l'intero puzzle bloccato.
La direzione opposta della dimostrazione non è così ovvia. Dobbiamo dimostrare che non ci sono puzzle interbloccati in cui tutte le file hanno solo 1 o 2 allungamenti. A partire da un paio di osservazioni:
- Le righe con solo 1 tratto non contribuiscono al blocco di un puzzle, poiché possono scorrere in entrambe le direzioni senza collisioni.
- Se tutte le righe con 2 tratti hanno lo stesso ordine di
A
e B
, il puzzle non è chiaramente bloccato. In questo caso, tutte le A
celle rimangono a sinistra di tutte le B
celle, o viceversa, e non vi sono collisioni quando si separano i due pezzi.
L'unico caso complicato sarebbero i puzzle in cui abbiamo file con 2 tratti di ordine diverso. Mostrerò che tali puzzle non esistono nelle specifiche indicate. Per mostrarlo, diamo un'occhiata a un puzzle parziale che ha questa configurazione, dove .
sono i caratteri jolly:
.......
AAABBBB
.......
BBAAAAA
.......
Ora, la specifica dice che sia il A
e B
le cellule sono semplicemente collegati in tutti i puzzle valide. Per rendere le A
celle collegate nel puzzle parziale sopra, abbiamo due opzioni:
Facciamo un giro attorno ad uno dei tratti di B
, ad esempio:
..AAAAAA
AAABBBBA
.......A
BBAAAAAA
........
Per fare questo, inevitabilmente estendiamo una delle file per avere 3 allungamenti, quindi questo non ci darà mai un puzzle valido in cui tutte le file hanno al massimo 2 allungamenti.
Li colleghiamo su un percorso diretto:
.......
AAABBBB
..A....
BBAAAAA
.......
Le A
celle ora sono semplicemente collegate e non ci sono ancora righe con più di 2 tratti. Tuttavia, anche le B
celle devono essere semplicemente collegate. Il percorso diretto è ora bloccato dalle A
celle collegate e l'unico modo per connettere le B
celle è di fare un giro attorno a uno dei tratti di A
celle. Questo porta al caso 1, dove non possiamo farlo senza creare file di 3 tratti.
Per contare i tratti, l'implementazione utilizza l'operatore CJam RLE.
Spiegazione del codice
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.