Задача гольфа состоит в том, чтобы закодировать и сжать следующее изображение в исходном файле.
Для этого нужно написать 3 функции: red
, green
и blue
которые принимают X / Y координаты изображения и возвращает соответствующий R / G / B значение пикселя между 0-255.
Вот тестовый код C / C ++:
#include <stdio.h>
#include "your_file"
int main() {
int x, y;
for(y = 0; y < 32; ++y)
for(x = 0; x < 32; ++x)
printf("%i %i %i\n", red(x, y), blue(x, y), green(x, y));
}
И вывод: http://pastebin.com/A770ckxL (вы можете использовать это для генерации данных вашего изображения)
Правила и детали:
- Это гольф
- Только ваш код / файл в гольфе - тестовый код является отдельным
- Используется набор символов ASCII, однако управляющие символы в строках могут использоваться только после экранирования (например, \ n, \ r и т. Д.).
- Все должно быть в источнике - без загрузки файла
- Ваш вывод должен соответствовать примеру вывода. Это означает сжатие без потерь.
Языки:
Проблема была написана с учетом C / C ++, но я снимаю эти ограничения. С учетом сказанного, я все еще рекомендую использовать их.
Ответы:
C
796 754 712 703 692 685 682 670 666 662 656648 символовChangelog:
return
к#define
, заменивif
с?
заявлением (спасибо @FUZxxl), удалениеint
из функций параметров списка.#define
p[]
и ещеh[]
некоторые?:
улучшенияb
такi
что больше не нужно.m=b
вместоm=11
иn<2e3
вместоi<356
- это близко к неопределенному поведению / повреждению памяти, но, кажется, мне повезло :)k
сейчас (32,16,8,4,2,1,0) вместо (5,4,3,2,1,0). Гоча, округ Колумбия;)p[]
иh[]
, превращенныйh[]
в…char*
оууу, в нем есть сонный котенок^<+_=>-
while
=>for
,l=l*2+...
=>l+=l+...
m=m>9?...
=>c[n++]=m>9?...
b[]
, поэтому мы можем отображать 64-127 вместо 0-63 и больше не нуждаемся в индексе битовk
. Спасибо, Петр Тарса . Заменено?:
(расширение GCC) на||
. Спасибо @JamesBp[]
)Изображение преобразуется в строку типа Base64 (ASCII 37-100) с использованием кодирования Хаффмана для кодирования цветов 0-9 с использованием 3-6 битов и специального цвета 10 (пиксель такой же, как у предыдущего) с использованием только 1 бита.
Скопированы две вещи из ответа Bunnit,
#define
и каждый раз целиком и полностью декодируется изображениеred
/green
/blue
. Есть место для дополнительных улучшений, так что ждите некоторых обновлений :) Я не уверен насчет соответствия кода, использовал GCC 4.6.1 для компиляции и тестирования.Что касается сжатия, я думаю, что арифметическое кодирование помогло бы, поскольку распределение довольно искажено, но, возможно, в этом случае издержки кода были бы слишком тяжелыми. LZW также должен делать очень хорошую работу. Цвета довольно локальны, поэтому адаптивное кодирование может быть идеей.
Более читаемая 754-символьная версия с некоторыми комментариями:
источник
int
из списков параметров, чтобы удалить еще несколько байтов.m=m>9?c[n-1]:m;
дляif(m>9)m=c[n-1];
?if(k<0){j=b[i++]-37;k=5;}
почему нетk>=0?:(j=b[i++]-37,k=5);
? (Этот код использует расширение C gcc,x=a?:b
такое же, какx=a?a:b
, с той разницей, что a оценивается только один раз.red(x,y){while(i<356){--k>=0?:(j=b[i++]-37,k=5);l*=2;if(j&(1<<k))l++;for(m=0;m<11;m++)l!=h[m]?:(m=m<=9?:c[n-1],c[n++]=m,l=0,m=12);}return P;}
Python (
684592 символа)Поскольку этот вызов теперь открыт для всех, почему бы и нет! Это знакомый маршрут кодирования zlib -> base64, поэтому я прошу прощения за это. Надеемся, что запись с некоторым подобием изобретательности будет короче!
Вот тестовый фрагмент, аналогичный оригиналу:
источник
C ++, 631 символ; С - 613
Унарный mtf-кодер base-92, C ++, 631 символ:
И версия C выше (613 символов):
Просто включить запись с данными base-95 и арифметическим кодированием + адаптивная статистическая модель.
Код schnaader использует ~ 438 символов для данных, а мой - только 318 (311 без маскировки).
Но, как и ожидалось, арифметическое кодирование слишком сложно для такой небольшой выборки, как эта.
(Это 844 символа)
Тесты (из более ранней версии base-96):
http://codepad.org/qrwuV3Oy
http://ideone.com/ATngC
Как-то ТАК ест 7F коды, поэтому пришлось обновить его до base = 95
источник
C ++ -
15251004964 символаСоздан массив z, в котором все возможные цвета хранятся как одно целое число (r << 16 | g << 8 | b). Создан массив d, в котором хранится {количество, значение}, значение - это позиция в массиве z, количество - это количество последовательных пикселей с этим значением. (Т. Е. 3,0, означает, что цвет 3 [0] появляется следующим 3 пиксели. Фактический массив пикселей (c) затем вычисляется каждый раз, когда вызывается красный цвет. Затем значение в массиве смещается вправо и выравнивается по необходимости, чтобы получить правильный компонент.
Я мог бы, вероятно, сохранить еще несколько символов (~ 50), выбрав больше шаблонов из массива, как определено.Edit 1 - изменил массив d для массива char с каждым смещением значения на 48, что означает, что я могу представить его как строку, сохраняющую загрузку запятых.
Редактировать 2 - Взял большую часть функций в операторе определения.
источник
int
(такint f(int x,int y)
становитсяf(x,y)
.Javascript,
696694 символаСпасибо Schnaader за 696 -> 694.
Я вычислил другой формат кодирования, который по сути представляет собой кодирование по длине прогона с таблицей соответствия цветов. Это работает довольно хорошо, потому что есть менее 16 цветов, и они появляются менее 16 раз подряд; поэтому каждое определение пикселя, включая длину, помещается в один байт. Я поместил цвет в верхнюю часть байта, а счет в нижнюю.
В итоге строка base64 оказалась длиннее, чем я ожидал (472 символа), но программа декодирования действительно короткая.
Примечание: я разделил код, чтобы иметь немного читабельности. Это должно быть на одной линии, чтобы бежать.
Тестовый код:
Я думаю, что результатом примера является вывод красного, зеленого, синего (а не красного, синего, зеленого, как в исходном тестовом коде); у меня все равно так работает.
источник
[0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894]
- это сохраняет 1 символ и имеет порядок GBR вместо RGB.C ++, 1357 символов
Деобфусцировал немного:
C
содержит значения RGB для десяти различных цветов изображения.E
содержит данные для изображения, где каждый элементE[i]
кодирует как счетчик повторений, такE[i]/10
и индекс цветаE[i]%10
.источник
int red(x,y){R Q(x+32*y)[0]}(only
# define`return
, то вы сможете побрить больше символов.Python 3 (589 символов)
Тестовый код
Основано на решении от Dillon Cower
источник
PHP (5.4) - 822
Я сделал это сознательно, не используя ни одну из встроенных функций сжатия . Это решение еще не закончено, я не уверен, что отказался, я вижу области для улучшения, но я не могу найти время / силу воли для того, чтобы провести весь процесс в настоящий момент, поэтому я публикую то, что я до сих пор.
Новые строки + комментарии должны быть удалены для 822 байтов.
Тестовая заглушка:
Сжатие самих данных изображения довольно хорошее, но функции для получения значений RGB занимают 1/4 кода.
Я использую пользовательский механизм кодирования длины base70 + run.
Закодированные данные изображения ссылаются на индекс массива RLE, который, в свою очередь, индексирует массив цветов. Я не уверен, сколько накладных расходов это добавляет или вычитает из-за прямой ссылки на цвета.
Синус есть 10 цветов (от 0 до 9), RLE хранятся как
run_length * 10 + colour_index
. Предоставление диапазона кодировок от 10 до 145 без экспериментов с оптимизацией на основе упорядочения цветов. (т. е. я мог бы сделать диапазон от 19 до 140, переместив цвета от 0 до 5, от 5 до 9 и от 9 до 0 - но это может иметь другие эффектные эффекты)Предыдущий ответ утверждает, что их закодированные данные составляют 472 байта. Мои данные закодированного изображения составляют 352 байта, но промежуточная RLE / карта цветов (которая не двоично закодирована) - это еще 129 байтов, в результате чего общее количество составляет 481. (а также дополнительные издержки для объединения двух). Однако я подозреваю, что мой метод может лучше масштабироваться для больших изображений.
ДЕЛАТЬ:
global
это сука, но не может получить доступ к индексам символов констант.источник
C (gcc) , 602 байта
Попробуйте онлайн!
Спуститься
источник