Этот вопрос основан на то , что я придумал , чтобы ответить на другой вопрос .
Иногда вопросы здесь просят нарисовать немного ASCII искусства. Одним простым способом хранения данных для искусства является RLE (кодирование по длине прогона) . Так:
qqqwwwwweeerrrrrtttyyyy
будет выглядеть так:
3q5w3e5r3t4y
Теперь, чтобы нарисовать большой ASCII-арт, вы можете получить такие данные (игнорируя символы новой строки):
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)
Символы, используемые для искусства ASCII, никогда не будут строчными или прописными буквами или цифрами, только знаками, знаками и символами, но всегда в наборе печатных символов ASCII.
Вы хотите сэкономить место в этой строке, поэтому вы заменяете числа набором символов в верхнем регистре (будучи «A» равно 1, «B» равно 2, пока «Z» не равно 26), потому что вы никогда не собираетесь получить более 26 повторений персонажа. Итак, вы получите:
S,T C(D)K@A$T K@S,O"D:T D)S,D:T K@
(Character count: 34)
И, наконец, вы замечаете, что некоторые группы (буква + символ) повторяются, поэтому вы заменяете группы, которые появляются в строке 3 раза или более, набором символов в нижнем регистре в порядке или появлении в строке, но сохраняя в буфере произведенные замены (в формате «группа + символ замены» для каждой замены) и оставшаяся часть строки как есть. Итак, следующие группы:
S, (3 times)
T (4 times)
K@ (3 times)
заменяется на 'a', 'b' и 'c' соответственно, потому что никогда не будет повторяться более 26 групп. Итак, наконец вы получите:
S,aT bK@c
abC(D)cA$bcaO"D:bD)aD:bc
(Character count: 9+24=33)
[Последний шаг сохраняет только 1 байт, потому что группы, которые фактически сохраняют символы после замены, - это группы, которые появляются 4 раза или более.]
Соревнование
Учитывая строку, содержащую данные RLE для рисования ASCII-графики (с предложенными ограничениями), напишите самую короткую программу / функцию / метод, которую вы можете, чтобы сжать ее, как описано. Алгоритм должен напечатать / вернуть две строки: первая содержит словарь, используемый для сжатия, а вторая - полученную сжатую строку. Вы можете вернуть строки в виде кортежа, массива, списка или чего-либо еще в указанном порядке.
Обратите внимание, что если строка не может быть сжата на шаге 2, алгоритм должен вернуть пустую строку в качестве первого возвращаемого значения и результат шага 1 в качестве второго возвращаемого значения.
Вам не нужно включать результат шага 1 в выходные значения, я просто включаю их в примеры для пояснения.
Это код-гольф , поэтому может быть самый короткий ответ для каждого языка!
Еще один тест
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
вероятно, будет храниться как просто S,T K@
без явного присвоения имен символам замещения, которые могут быть тривиально выведены из этого.