Ваша миссия сегодня состоит в том, чтобы изобрести текстовый компрессор.
задача
Вы напишите две функции:
Пакера является функцией , которая принимает строку ASCII символов (U + 0000 до U + 007F) и выводит строку Unicode (U + 0000 до U + 10FFFF), содержащие наименьшее количество символов возможно.
Распаковщик это функция , которая принимает кодированные строки Unicode и выводит в точности исходной строки ASCII.
вход
Единственным разрешенным вводом является строка ASCII (для упаковщика) и упакованная строка Юникода (для распаковщика). Нет ввода пользователя, нет подключения к Интернету, нет использования файловой системы.
Ваши функции могут иметь доступ к этому списку английских слов . Вы можете использовать этот список как локальный текстовый файл или скопировать его содержимое в исходный код в виде строки или массива строк .
Вы не можете жестко закодировать фрагменты ниже в ваших функциях.
Выход
Единственным разрешенным выходом для обеих функций является строка.
Выходные данные распаковщика должны содержать те же символы, что и входные данные упаковщика.
Ваши входы и выходы могут использовать любую кодировку символов, поддерживающую весь Unicode (UTF-8/16/32, GB18030, ...), так как ваш результат будет зависеть только от количества символов Unicode в выходных данных. Пожалуйста, уточните, какую кодировку вы используете.
Чтобы подсчитать количество символов Unicode в вашем выводе, вы можете использовать этот инструмент: http://mothereff.in/byte-counter
счет
Ваша запись должна быть в состоянии упаковать и распаковать 10 следующих фрагментов текста (которые я взял на этом форуме).
Ваша оценка будет равна сумме размеров ваших 10 упакованных строк (в символах Юникода) + размер ваших двух функций (также в символах Юникода)
Не считайте размер словаря, если вы его используете.
Пожалуйста, включите в свои записи «оценку» каждого фрагмента и его упакованную версию.
Самый низкий балл побеждает.
Данные
Вот фрагменты для кодирования, чтобы вычислить ваш счет:
1: Тексты песен Рика Ролла (1870b): Мы не новички в программировании гольфа, вы знаете правила, и я тоже
Мы не новички в любви Вы знаете правила и я тоже Я всегда думаю о полной приверженности Вы не получите это от любого другого парня Я просто хочу рассказать вам, как я себя чувствую Должен заставить тебя понять Никогда тебя не брошу Никогда не подведу Никогда не побегу и не покину тебя Никогда не заставлю тебя плакать Никогда не прощаюсь Никогда не скажу неправду и не сделаю тебе больно Мы знали друг друга так долго Твое сердце болит, но Ты стесняешься сказать это Внутри мы оба знаем, что происходит Мы знаем игру и будем играть в нее И если вы спросите меня, как я себя чувствую Не говори мне, что ты слишком слеп, чтобы видеть Никогда тебя не брошу Никогда не подведу Никогда не побегу и не покину тебя Никогда не заставлю тебя плакать Никогда не прощаюсь Никогда не скажу неправду и не сделаю тебе больно Никогда тебя не брошу Никогда не подведу Никогда не побегу и не покину тебя Никогда не заставлю тебя плакать Никогда не прощаюсь Никогда не скажу неправду и не сделаю тебе больно (Ох, сдавайся) (Ох, сдавайся) (Ох) Никогда не дам, никогда не дам (Откажусь) (Ох) Никогда не дам, никогда не дам (Откажусь) Мы знаем друг друга так долго Твое сердце болит, но Ты стесняешься сказать это Внутри мы оба знаем, что происходит Мы знаем игру и будем играть в нее Я просто хочу рассказать вам, как я себя чувствую Должен заставить тебя понять Никогда тебя не брошу Никогда не подведу Никогда не побегу и не покину тебя Никогда не заставлю тебя плакать Никогда не прощаюсь Никогда не скажу неправду и не сделаю тебе больно Никогда тебя не брошу Никогда не подведу Никогда не побегу и не покину тебя Никогда не заставлю тебя плакать Никогда не прощаюсь Никогда не скажу неправду и не сделаю тебе больно Никогда тебя не брошу Никогда не подведу Никогда не побегу и не покину тебя Никогда не заставлю тебя плакать Никогда не прощаюсь Никогда не скажу неправду и не сделаю тебе больно
2: Гольфист (412b): гольф ASCII-арт
'\. , |> 18 >> \. '. | О >> 'о | \. | / \. | / /. ' | JGS ^^^^^^^ `^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^
3: номер ромба (233b): напечатать этот алмаз
1 121 12321 1234321 123454321 12345654321 1234567654321 123456787654321 12345678987654321 123456787654321 1234567654321 12345654321 123454321 1234321 12321 121 1
4: алфавит четыре раза (107b): печатать алфавит четыре раза
АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ qwertyuiopasdfghjklzxcvbnm pyfgcrlaoeuidhtnsqjkxbmwvz zyxwvutsrqponmlkjihgfedcba
5: Текст старого Макдональда (203b): функция Старого Макдональда
У старого Макдональда была ферма, EIEIO, И на той ферме у него была корова, EIEIO, С Му Му здесь и Му Му там, Вот му, там му, везде му му, У старого Макдональда была ферма, EIEIO!
6: Рок круглосуточно (144b): Рок круглосуточно
1, 2, 3 часа, 4 часа рок, 5, 6, 7 часов, 8 часов рок, 9, 10, 11 часов, 12 часов рок, Сегодня вечером мы будем качаться круглосуточно.
7: Hello World (296b): Скажите «Hello» миру в искусстве ASCII
_ _ _ _ _ _ _ | | | | ___ | | | ___ __ _____ _ __ | | __ | | | | | _ | | / _ \ | | / _ \ \ \ / \ / / _ \ | «__ | | / _` | | | _ | __ / | | (_) | \ VV / (_) | | | | (_ | | _ | | _ | | _ | \ ___ | _ | _ | \ ___ () \ _ / \ _ / \ ___ / | _ | | _ | \ __, _ (_) | /
8: ирландское благословение (210b): старое ирландское благословение
Пусть дорога поднимется навстречу тебе Пусть ветер всегда будет у тебя за спиной Пусть солнце сияет на вашем лице Дожди падают на твои поля И пока мы не встретимся снова Пусть Бог держит тебя в дупле Своей руки
9: Была лирика старой леди (1208b): Там была старая леди
Была пожилая женщина, которая проглотила муху. Я не знаю, почему она проглотила эту муху, Возможно, она умрет. Была пожилая женщина, которая проглотила паука, Это извивалось, покачивалось и покачивалось внутри нее. Она проглотила паука, чтобы поймать муху, Я не знаю, почему она проглотила эту муху, Возможно, она умрет. Была пожилая женщина, которая проглотила птицу, Как нелепо глотать птицу. Она проглотила птицу, чтобы поймать паука, Она проглотила паука, чтобы поймать муху, Я не знаю, почему она проглотила эту муху, Возможно, она умрет. Была пожилая женщина, которая проглотила кошку, Представь, что глотать кошку. Она проглотила кошку, чтобы поймать птицу, Она проглотила птицу, чтобы поймать паука, Она проглотила паука, чтобы поймать муху, Я не знаю, почему она проглотила эту муху, Возможно, она умрет. Была пожилая женщина, которая проглотила собаку, Какая свинья, чтобы проглотить собаку. Она проглотила собаку, чтобы поймать кошку, Она проглотила кошку, чтобы поймать птицу, Она проглотила птицу, чтобы поймать паука, Она проглотила паука, чтобы поймать муху, Я не знаю, почему она проглотила эту муху, Возможно, она умрет. Была пожилая женщина, которая проглотила лошадь, Она умерла, конечно.
10: адрес Геттисберга (1452b): насколько случайным является адрес Геттисберга
Четыре десятка и семь лет назад наши отцы создали на этом континенте новую нацию, зачатую в свободе и посвященную утверждению, что все люди созданы равными. Сейчас мы вовлечены в великую гражданскую войну, проверяя, может ли эта нация или любая нация, столь задуманная и столь преданная, долго существовать. Мы встретились на великом поле битвы этой войны. Мы пришли, чтобы посвятить часть этой области как место последнего упокоения тем, кто здесь отдал свои жизни за то, чтобы этот народ мог жить. Это вполне уместно и правильно, что мы должны сделать это. Но, в более широком смысле, мы не можем посвятить, мы не можем посвятить, мы не можем освящать эту землю. Храбрые люди, живые и мертвые, которые боролись здесь, освятили это, намного выше нашей бедной силы добавлять или отвлекать. Мир мало заметит, и долго не вспомнит, что мы здесь говорим, но он никогда не забудет, что они здесь сделали. Скорее, мы живем, чтобы посвятить себя здесь незавершенной работе, которую они так велико продвинули до сих пор. Скорее, мы должны быть здесь преданы великой задаче, стоящей перед нами - что из этих почитаемых мертвецов мы берем повышенную преданность тому делу, ради которого они в последний раз проявили преданность, - что мы здесь решительно решаем, что эти мертвые не будут напрасно умерли - что этот народ под Богом получит новое рождение свободы - и что народное управление народами для народа не погибнет от земли.
Всего (без сжатия): 6135 символов / байт.
Повеселись!
private static final String RICK_ROLL_RETURN = "We're no strangers to love...
Ответы:
Хаскелл - 5322 балла
Байт кода:
686
Первоначальный размер :
6147
= 1871+415+234+108+204+145+297+211+1209+1453
Закодированный размер:
4636
= 1396+233+163+92+153+115+197+164+979+1144
Гол :
686+ 4636
Сжатие количества символов:
~25%
Код
Помимо оптимизаций, это сохраняет значения между
0
и7f
в символах Юникода как их главные факторы.Это не уменьшает количество байтов кодированного вывода, оно только уменьшает количество символов Unicode. Например, тест № 4 содержит
108
символы и закодированный вывод92
. Их соответствующие размеры, однако,108
и364
байты.Как это работает
кодирование
n
.n
затем преобразуется в список его основных факторовps
.1
. Это означает, что они, факторы, могут храниться в виде индексов всего в 5 битах.1
это особый случай и представлен пустым списком.ps
кодировки теперь можно начинать.ps
преобразуется в его индекс в списке из 32 уникальных факторов (в приведенном выше коде этот список обозначен какa
).ps
необходимо сплющить. Для сохранения целостности данных каждый список преобразуется в другой список из двух частей.fs
.fs
могут быть упакованы в символы Юникода, используя сдвиг битов.Декодирование
1
вписывается в это, я хотел бы напомнить вам об этомproduct [] == 1
.тесты
Использование этого интерфейса для тестирования было бы болезненным, поэтому я использовал эту функцию, чтобы получить результаты ниже.
Образец
Вывод функции кодирования
g
для теста № 4 такой"\99429\582753\135266\70785\35953\855074\247652\1082563\68738\49724\164898\68157\99429\67973\1082404\587873\73795\298017\330818\198705\69861\1082435\595009\607426\36414\69873\855074\265249\346275\67779\68738\77985\1082513\821353\132131\101410\247652\1082562\49724\164898\67649\594977\34915\67746\50273\135265\103997\563265\103457\1086021\99399\584802\70753\73889\34882\582722\411459\67779\68740\1084516\1082563\1091681\103491\313282\49724\164897\68705\135741\69858\50241\607426\35905\608421\1082435\69858\50274\71777\43075\298018\280517\1082404\67971\36017\955425\67665\919600\100452\132129\214883\35057\856097\101474\70753\135737"
или, если вы адепт тарабарщины, это
𘑥𡁢𑒁豱𐲂숼𨐢𘑥𐦅𒁃𰠱𑃥踾𑃱𐲂𓂡𠐣𘰢숼𨐢𐡁衣쑡𡁡𘑇𑑡𒂡衂𐲄숼𨐡𡈽𑃢쑁豁𑃢쑢ꡃ𐦃貱𐡑𘡤𠐡裱𘱢𑑡𡈹
Дополнительные заметки
edTest
размер тестов согласованы, но все же отличаются от указанного размера в вопросе.—
) , что я заменен ,-
так как они находятся вне0
-7f
диапазона.00
базовом случае,01
повторить все,10
повторить, кроме последнего,11
повторить, кроме двух последних.источник
abcdefghijklm...
в𘑥𡁢𑒁豱...
, не могли бы вы объяснить это немного подробнее, пожалуйста? Кроме того, я исправил количество символов и преобразовал тире # в вопросе 10. Мои чары все еще отличаются от ваших. Не знаю почему, я использовал инструмент mothereff.in.C ++ (C ++ 11), 2741 баллов
Этот ответ использует UTF-32 в качестве кодировки для сжатого текста.
Подсчет и подсчет символов
Код: 593 символа (завершающий символ новой строки убран)
Сжатые тексты (символы Юникода) : 654 + 145 + 82 + 38 + 51 + 104 + 73 + 423 + 506 = 2148 (считается
wc -m
для количества символов Юникода, а не байтов, число байтов, как и в ответе @ gxtaillon) , выше, чем оригиналы, всего 8413 байт, как считаетсяwc -c
).Коэффициент сжатия (ASCII к Unicode) : 35,01% (используя 6135 байт из вопроса (так же, как
wc -c
))Осторожно:
Многие оболочки не могут обрабатывать символы Юникода, которые производит эта программа. Таким образом, распаковка может привести к тому, что текст будет где-то обрезан, когда оболочка не сможет обработать символ, так как ввод осуществляется через
stdin
оболочку.составление
Он должен компилироваться с
clang++
иg++ -std=c++11
, но он покажет некоторые предупреждения о приоритете операторов, так как выражение likeb<<20-n&0xFFFFF
будет восприниматься не так((b << 20) - n) & 0xFFFFF
, как можно было бы ожидать, а скорее как(b << (20 - n)) & 0xFFFFF
.использование
./compress
../compress c
для сжатия, так и./compress d
для распаковки. (Осторожно, опуская опцию, вы получите SEGFAULT (проверка ошибок настолько символична ...), а другие опции (например, использованиеD
вместоd
) могут дать неожиданные результаты.stdin
а вывод записывается вstdout
Как это работает
Ungolfed
объяснение
Поскольку все символы Юникода от
U+0000
доU+10FFFF
разрешены, мы можем использовать 20 бит на символ юникода:U+FFFFF
использует 20 бит и все еще включен в допустимый диапазон. Таким образом, мы просто пытаемся втиснуть все отдельные биты ASCII-символов в символы Unicode, чтобы сохранить несколько символов ASCII в одном символе Unicode. Однако нам также необходимо сохранить количество битов, использованных в последнем символе Юникода, поскольку в противном случае неиспользуемые биты мусора могут быть интерпретированы как надлежащие сжатые символы ASCII. Поскольку максимальное количество используемых битов в последнем символе юникода равно 20, нам потребуется 5 битов, которые помещаются в начало сжатых данных.Пример вывода
Это вывод для примера # 4 (как указано
less
):(
쏏𦛏
укажите в<U+C3CF><U+266CF>
качестве кодов символов, но я мог ошибиться)источник
Python 3, 289 + 818 = 1107 баллов
Только слегка в гольф.
Общий размер кода составляет 289 байт и кодирует данные 6135 байт в 818 символов Unicode - общее количество выходных байтов составляет 3201 байт, что значительно меньше исходных входных данных.
Кодирует, используя zlib, затем вторично, используя кодировку Unicode. Некоторая дополнительная логика была необходима, чтобы избежать суррогатов (что Python действительно ненавидит).
Пример вывода из # 4, как видно из
less
(37 символов Unicode):Программа драйвера для тестирования:
Количество выходных байтов:
источник
p
упаковщик,u
распаковщик.Python 2 - 1141 балл
Размер кода составляет
281
байты, и он кодирует6135
байты в860
символы Юникода.Как это работает:
Кодировать:
19
битов, добавить1
бит в начало каждого из них, а затем преобразовать в символы Юникода.Декодирование обратное.
Обратите внимание, что некоторые версии Python могут обрабатывать только символы Unicode до
0xFFFF
, и, таким образом, этот код будет вызывать aValueError
.источник