Esta pregunta se basa en lo que se me ocurrió para responder otra pregunta .
A veces las preguntas aquí piden dibujar un poco de arte ASCII. Una forma sencilla de almacenar los datos para el arte es RLE (codificación de longitud de ejecución) . Entonces:
qqqwwwwweeerrrrrtttyyyy
se convierte en:
3q5w3e5r3t4y
Ahora, para dibujar un gran arte ASCII, es posible que obtenga datos como este (ignorando los nuevos caracteres de línea):
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)
Los caracteres utilizados para el arte ASCII nunca serán letras o números en minúsculas o mayúsculas, solo signos, marcas y símbolos, pero siempre en el conjunto de caracteres ASCII imprimible.
Desea ahorrar algo de espacio en esa cadena, por lo que reemplaza los números con el conjunto de caracteres en mayúscula (siendo 'A' es igual a 1, 'B' es igual a 2 hasta que 'Z' es igual a 26), porque nunca va a obtener más de 26 repeticiones de un personaje. Entonces obtienes:
S,T C(D)K@A$T K@S,O"D:T D)S,D:T K@
(Character count: 34)
Y finalmente observa que algunos grupos de (letra + símbolo) se repiten, por lo que sustituye los grupos que aparecen 3 veces o más en la cadena por el conjunto de caracteres en minúscula, en orden o en la apariencia de la cadena, pero almacenando en un búfer el sustituciones realizadas (en el formato "grupo + sustitución char" para cada sustitución), y dejando el resto de la cadena como está. Entonces los siguientes grupos:
S, (3 times)
T (4 times)
K@ (3 times)
se sustituye por 'a', 'b' y 'c', respectivamente, porque nunca habrá más de 26 grupos que se repitan. Entonces finalmente obtienes:
S,aT bK@c
abC(D)cA$bcaO"D:bD)aD:bc
(Character count: 9+24=33)
[El último paso solo guarda 1 byte porque los grupos que realmente guardan caracteres después de ser sustituidos son los que aparecen 4 veces o más.]
El reto
Dada una cadena que contiene los datos RLE para dibujar un arte ASCII (con las restricciones propuestas), escriba el programa / función / método más corto que pueda para comprimirlo como se describe. El algoritmo debe imprimir / devolver dos cadenas: la primera que contiene el diccionario utilizado para la compresión y la segunda es la cadena comprimida resultante. Puede devolver las cadenas como una tupla, una matriz, una lista o lo que sea, en el orden dado.
Tenga en cuenta que si la cadena no se puede comprimir en el paso 2, el algoritmo debe devolver una cadena vacía como primer valor de retorno y el resultado del paso 1 como segundo valor de retorno.
No es necesario incluir el resultado del paso 1 en los valores de salida, solo los incluyo en los ejemplos para fines de aclaración.
Este es el código de golf , ¡así que puede ganar la respuesta más corta para cada idioma!
Otro caso de prueba
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
probablemente se almacenaría simplemente S,T K@
sin nombrar explícitamente los caracteres de sustitución que se pueden deducir trivialmente de eso.