Вызов
Напишите программу, которая сжимает и распаковывает текст ASCII без потерь. Он должен быть специализированным, чтобы хорошо работать с палиндромами, в том числе с нечувствительным к регистру и с пунктуацией палиндромами. Лучшее сжатие с наименьшим источником выигрывает.
счет
total_bytes_saved / sqrt(program_size)
- выигрывает самый высокий балл
total_bytes_saved
На сколько байт меньше сжатых строк, чем оригиналов, всего в тестовых примерах ниже. program_size
это размер в байтах исходного кода программ сжатия и распаковки. Код, общий для двух, должен учитываться только один раз.
Например, если есть 10 тестовых случаев и 100-байтовая программа сохранила 5 байтов на 7 тестовых случаях, по 10 на 2 из них, но последний тестовый случай был на 2 байта длиннее, решение получило бы 5,3. ( (7 * 5 + 10 * 2 - 2) / sqrt(100) = 5.3
)
Тестовые случаи
tacocat
toohottohoot
todderasesareddot
amanaplanacanalpanama
wasitacaroracatisaw?
Bob
IManAmRegalAGermanAmI
DogeeseseeGod
A Santa at NASA
Go hang a salami! I'm a lasagna hog.
правила
- Применяются стандартные лазейки.
- Сжатие должно работать со всеми печатаемыми текстовыми строками ASCII (байты 32-126 включительно), а не только с палиндромами. Однако на самом деле не нужно экономить место для каких-либо входов.
- Вывод может быть любой последовательностью байтов или символов, независимо от ее реализации или внутреннего представления (например, строки, списки и массивы - это честная игра). При кодировании в UTF-8 считайте байты, а не символы. Широкие строки (например, UTF-16 или UTF-32) не допускаются, если только возможные кодовые точки находятся в диапазоне от 0 до 255.
- Встроенные функции сжатия / распаковки не допускаются.
Для собственного удовольствия опубликуйте сжатые строки с вашим исходным кодом.
ОБНОВЛЕНИЕ 1: Оценка изменена с total_bytes_saved / program_size
на total_bytes_saved / sqrt(program_size)
, чтобы придать больший вес лучшей компрессии и меньший вес агрессивным играм в гольф. Скорректируйте свои оценки соответственно.
UPDATE 2: фиксированный , wasitacaroraratisaw?
чтобы бытьwasitacaroracatisaw?
источник
wasitacaroraratisaw?
это контрпример к этому[32-126]
?1000 *
роль действительно нужна, и нет, я не думаю, что это заставит счет чувствовать себя более «удовлетворительным»;)Ответы:
JavaScript (ES6), 3,143 (81 байт сохранен, программа 664 байт)
Теперь, когда я вполне доволен этой программой (и системой подсчета очков), я напишу немного объяснения.
Основная идея состоит в том, чтобы сжать входные данные в строку битов, а затем сжать каждый набор из 8 битов в байт. В целях объяснения я просто манипулирую битовой строкой.
Строка битов может быть разделена на несколько разделов:
Заголовок очень простое отображение:
Буквенные данные также довольно просты. Во-первых, все не-буквы извлекаются из строки, а все буквы переводятся в верхний регистр. Если полученная строка является палиндромом, обратная половина обрезается. Затем это отображение применяется:
Этот раздел заканчивается с
111
. После этого идут данные стилей, в которых хранятся данные верхнего и нижнего регистра и не буквы. Это работает так:Итак, пройдя через пример, показанный выше, мы имеем
Когда достигнут конец строки битов, все остальные символы из буквенных данных добавляются к результату. Это избавляет нас от необходимости делать последнее
000...001
и позволяет нам обрезать эти биты из строки.Проходя тестовые случаи:
источник
Bob
.Bob
действительно просто встал на свои места - 1 бит для заголовка, 10 + 3 бита для двух букв и 2 бита для одной заглавной буквы. Я не смог бы сделать это-0+9
+9
будет соответствовать строке, а-~8
будет делать+9
арифметически (поскольку-
ничего не делает для строк, поэтому он интерпретирует его как число). В этом случае-~8
довольно умный. :) Хороший ответ, кстати, +1 от меня! Очень умно хранить всю информацию в таких битах, даже сохраняя байтBob
.Python 2: 2.765 (70 байт сохранено, программа 641 байт)
Я немного изменил свой подход. Теперь он хорошо работает на несовершенных палиндромах. Там нет сжатых строк, которые будут длиннее, чем ввод. Идеальный палиндром ровной длины всегда сжимает до 50% от исходного размера.
Результаты
И в качестве бонуса он экономит 6 байт на моем неверном палиндроме, который у меня был раньше.
объяснение
Декомпрессия использует стек. Кодовые точки 32-127 трактуются буквально. Если символ является буквой, значение также помещается в стек. Значения 128-192 используются для букв с перестановкой регистра, поэтому буква с учетом регистра (
o^32
из-за того, как ASCII выложен) помещается в стек, а обычная буква добавляется в строку. Значения 192-255 используются для добавления букв без добавления в стек, поэтому это используется, когда буквы не совпадают, и для средней буквы в палиндромах нечетной длины. Кодовые точки 1-15 указывают, что стек должен выталкиваться такое количество раз. Кодовые точки 17-31 похожи, но они сначала печатают пробел перед тем, как выскочить из стека. Существует также неявная инструкция «pop to empty» в конце ввода.Компрессор работает с обоих концов и складывает соответствующие буквы в значения 1-31. Он пропускает не-буквы. Когда буквы совпадают, но регистр не соответствует, он добавляет 64 к левой букве и увеличивает правую букву. Это позволяет сэкономить место на
IManAmRegalAGermanAmI
. В середине или когда буквы не совпадают, он поворачивается на 128 с обеих сторон. Я не могу добавить туда, потому что мне нужно избегать особого случая, когдаleft == right
. При сворачивании соседних поп-маркеров на правой стороне я должен убедиться, что соседний не перетечет в кодовую точку 16, потому что это нужно для пробелов. (На самом деле это не проблема ни для одной из строк тестового примера)РЕДАКТИРОВАТЬ 1 : Нет больше безголовой версии.
источник
Python3, 1,833 (25 байт сохранено, программа 186 байт)
Простое энтропийное кодирование с равной вероятностью 0-го порядка. Нет палиндром-специфических оптимизаций.
источник
Java 8, оценка: 1.355 (20 байтов сохранено / 218 (107 + 111) байтов)
Функция сжатия (содержит три непечатаемых символа ASCII):
Функция распаковки (содержит два непечатаемых символа ASCII):
Объяснение:
Попробуйте онлайн.
Сжимает только идеальные палиндромы.
источник