Questa domanda si basa su ciò che mi è venuto in mente per rispondere a un'altra domanda .
A volte le domande qui pongono per disegnare un po 'di arte ASCII. Un modo semplice per archiviare i dati per l'arte è RLE (codifica di lunghezza di esecuzione) . Così:
qqqwwwwweeerrrrrtttyyyy
diventa:
3q5w3e5r3t4y
Ora per disegnare una grande arte ASCII potresti forse ottenere dati come questo (ignorando i nuovi caratteri di linea):
19,20 3(4)11@1$20 11@19,15"4:20 4)19,4:20 11@
^^^
Note that this is "20 whitespaces"
(Character count: 45)
I caratteri utilizzati per l'arte ASCII non saranno mai lettere minuscole o maiuscole o numeri, solo segni, segni e simboli, ma sempre nel set di caratteri ASCII stampabile.
Vuoi risparmiare un po 'di spazio in quella stringa, quindi sostituisci i numeri con il set di caratteri maiuscoli (essendo' A 'uguale a 1,' B 'è uguale a 2 fino a quando' Z 'è uguale a 26), perché non hai mai intenzione di ottieni più di 26 ripetizioni di un personaggio. Quindi ottieni:
S,T C(D)K@A$T K@S,O"D:T D)S,D:T K@
(Character count: 34)
E infine noti che alcuni gruppi di (lettera + simbolo) si ripetono, quindi sostituisci i gruppi che compaiono 3 volte o più nella stringa dal set di caratteri minuscoli, nell'ordine o nell'aspetto nella stringa, ma memorizzando in un buffer il sostituzioni effettuate (nel formato "gruppo + carattere sostitutivo" per ciascuna sostituzione), lasciando il resto della stringa così com'è. Quindi i seguenti gruppi:
S, (3 times)
T (4 times)
K@ (3 times)
viene sostituito da 'a', 'b' e 'c', rispettivamente, perché non ci saranno mai più di 26 gruppi che si ripetono. Quindi finalmente ottieni:
S,aT bK@c
abC(D)cA$bcaO"D:bD)aD:bc
(Character count: 9+24=33)
[L'ultimo passaggio salva solo 1 byte perché i gruppi che salvano effettivamente i caratteri dopo essere stati sostituiti sono quelli che appaiono 4 volte o più.]
La sfida
Data una stringa contenente i dati RLE per disegnare un'arte ASCII (con le restrizioni proposte), scrivi il programma / funzione / metodo più breve che puoi per comprimerlo come descritto. L'algoritmo deve stampare / restituire due stringhe: la prima contenente il dizionario utilizzato per la compressione e la seconda è la stringa compressa risultante. Puoi restituire le stringhe come una Tupla, una matrice, una Lista o qualsiasi altra cosa, nell'ordine dato.
Si noti che se la stringa non può essere compressa nel passaggio 2, l'algoritmo deve restituire una stringa vuota come primo valore restituito e il risultato del passaggio 1 come secondo valore restituito.
Non è necessario includere il risultato del passaggio 1 nei valori di output, li includo solo negli esempi a scopo di chiarimento.
Questo è code-golf , quindi può vincere la risposta più breve per ogni lingua!
Un altro caso di test
Input: 15,15/10$15,15/10"10$10"10$10"10$10"15,15/
Output of step 1: O,O/J$O,O/J"J$J"J$J"J$J"O,O/
Final algorithm output: O,aO/bJ$cJ"d
abcabdcdcdcdab
---
Input: 15,15/10$15,15/10"
Output of step 1: O,O/J$O,O/J"
Final algorithm output: <empty string>
O,O/J$O,O/J"
S,aT bK@c
verrebbero probabilmente archiviati semplicemente S,T K@
senza nominare esplicitamente i caratteri di sostituzione che possono essere banalmente dedotti da quello.