Esta pergunta é baseada no que eu vim para responder a outra pergunta .
Às vezes, as perguntas aqui pedem para desenhar alguma arte ASCII. Uma maneira simples de armazenar os dados para a arte é o RLE (codificação em tamanho de execução) . Então:
qqqwwwwweeerrrrrtttyyyy
torna-se:
3q5w3e5r3t4y
Agora, para desenhar uma grande arte ASCII, talvez você esteja obtendo dados como este (ignorando os novos caracteres de linha):
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)
Os caracteres usados para a arte ASCII nunca serão letras ou números em minúsculas ou maiúsculas, apenas sinais, marcas e símbolos, mas sempre no conjunto de caracteres ASCII imprimíveis.
Você deseja economizar espaço nessa sequência, substituindo os números pelo conjunto de caracteres em maiúsculas (sendo 'A' igual a 1, 'B' igual a 2 até 'Z' igual a 26), porque você nunca vai obtenha mais de 26 repetições de um personagem. Então você obtém:
S,T C(D)K@A$T K@S,O"D:T D)S,D:T K@
(Character count: 34)
E, finalmente, você percebe que alguns grupos de (letra + símbolo) estão se repetindo; portanto, você substitui os grupos que aparecem 3 vezes ou mais na cadeia de caracteres pelo conjunto de caracteres em minúsculas, na ordem ou aparência da cadeia, mas armazenando em um buffer o substituições feitas (no formato "grupo + char de substituição" para cada substituição) e deixando o restante da string como está. Portanto, os seguintes grupos:
S, (3 times)
T (4 times)
K@ (3 times)
é substituído por 'a', 'b' e 'c', respectivamente, porque nunca haverá mais de 26 grupos repetindo. Então, finalmente, você obtém:
S,aT bK@c
abC(D)cA$bcaO"D:bD)aD:bc
(Character count: 9+24=33)
[A última etapa salva apenas 1 byte porque os grupos que realmente salvam caracteres após serem substituídos são os que aparecem 4 vezes ou mais.]
O desafio
Dada uma sequência que contém os dados do RLE para desenhar uma arte ASCII (com as restrições propostas), escreva o programa / função / método mais curto possível para compactá-lo conforme descrito. O algoritmo deve imprimir / retornar duas strings: a primeira contendo o dicionário usado para a compactação e a segunda sendo a string compactada resultante. Você pode retornar as seqüências de caracteres como uma tupla, uma matriz, uma lista ou qualquer outra coisa, na ordem especificada.
Observe que, se a sequência não puder ser compactada na etapa 2, o algoritmo deverá retornar uma sequência vazia como primeiro valor de retorno e o resultado da etapa 1 como segundo valor de retorno.
Você não precisa incluir o resultado da etapa 1 nos valores de saída, apenas os incluo nos exemplos para fins de esclarecimento.
Este é o código-golfe , por isso a resposta mais curta para cada idioma ganha!
Outro caso de teste
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
provavelmente seria armazenado como apenas S,T K@
sem nomear explicitamente os caracteres de substituição que podem ser deduzidos trivialmente disso.