Формат PBM (Portable BitMap) - это очень простой черно-белый растровый формат ASCII.
Вот пример для буквы «J» (скопировано из ссылки в википедии):
P1 # Это пример растрового изображения буквы "J" 6 10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Пришло время создать небольшой инструмент для создания файлов в этом изящном маленьком формате!
Ваша цель - написать самую короткую программу (на любом языке), которая соответствует следующим правилам:
- Ваша программа берет одну строку из стандартного ввода (например
CODEGOLF.STACKEXCHANGE.COM!
) - Он генерирует файл PBM с растровым (читаемым) представлением строки.
- Каждый персонаж построен как сетка 8x8.
- Вы должны поддерживать символы [AZ] (все заглавные буквы), пробел, точку ('.') И восклицательный знак ('!').
- Не допускаются внешние библиотеки (конечно, нет связанных с PBM)!
- Используемый набор символов не должен быть просто внешним по отношению к вашей программе. Часть проблемы - эффективное хранение персонажей ...
Проверка на достоверность формата PBM может быть выполнена с помощью GIMP (или других). Продемонстрируйте пример ввода и вывода!
Самое короткое решение получит баллы за ответы 2012-01-31.
Удачи в гольф!
PS: я добавил награду (в процентном отношении огромную часть моей репутации Codegolf), чтобы (надеюсь) привлечь больше конкурентов.
code-golf
string
graphical-output
ChristopheD
источник
источник
letters
другими словами). Не похоже на пример, связанный с.Ответы:
GolfScript, 133 байта
Это основано на моем 164-байтовом решении Perl и использует тот же самый шрифт размером 4 на 5 пикселей. Опять же, сначала я приведу читаемую версию:
Здесь
FONT DATA HERE
стоит 71 байт двоичных упакованных данных шрифта. Кодировка немного отличается от версии Perl: вместо того, чтобы разбивать упакованную строку на пробел, я сначала расширяю ее, а затем делю на клочок3
(выбранный, потому что это просто не происходит нигде в шрифте).Поскольку данные шрифта в реальном скрипте содержат непечатаемые символы, я даю их в виде шестнадцатеричного дампа ниже. Используйте,
xxd -r
чтобы превратить шестнадцатеричный дамп обратно в исполняемый код GolfScript:В отличие от Perl скрипта, этот код печатает символы вне набора
A
-Z
,!
,.
,space
в смешных выглядящие маленькие закорючки. Замена заглушек заготовками обойдется в 2 дополнительных символа; их полное удаление будет стоить 4.Это моя первая программа на GolfScript, поэтому я не удивлюсь, если останется место для оптимизации. Вот как это работает:
{91,65>"!. "+?}%:s
отображает допустимые символы ввода (A
-Z
,!
,.
,space
) к номерам 0 - 28 и присваивает результатs
. Любые символы вне допустимого набора сопоставляются с -1, что и приводит к появлению загогулин при печати."P4"\,8*8
толкает значения «P4», в 8 раз превышающие длину ввода, и 8 в стек. При печати в конце они сформируют заголовок PBM.{16base}%[3]/
берет предыдущую строку данных шрифта, разбивает каждый ее байт на два куска и разбивает результат на блоки, разделенные значением3
.{:p;{[p=0]0=}s%}%
затем зацикливается на этих блоках, сначала присваивая каждый блок переменной,p
а затем зацикливаясь на переназначенной входной строкеs
, заменяя каждый символ значением соответствующего смещения вp
. Забавно выглядящая конструкция[p=0]0=
делает то же самоеp=
, за исключением того, что она возвращает 0 для любых смещений после концаp
; Мне это не очень нравится, но я не смог придумать более короткий способ справиться с этим.Наконец,
]n*
берет все в стеке (три значения заголовка и массив данных изображения) и соединяет их вместе с символами новой строки для печати.источник
Perl, 164 байта, без сжатия zlib / gzip
Поспав о проблеме, мне удалось найти гораздо более короткое решение, чем первое. Хитрость заключается в том, чтобы использовать небольшую лазейку в правилах: символы должны соответствовать 8 на 8 пикселей каждый, но ничто не говорит о том, что они должны заполнить все это пространство. Поэтому я нарисовал свой собственный шрифт размером 4 на 5 пикселей, что позволило мне упаковать два символа в 5 байтов.
Вывод выглядит так:
(масштабируется х 4)
(оригинальный размер)
Прежде чем дать реальный код со встроенными данными шрифта, позвольте мне показать версию для игры в гольф:
В реальном коде
PACKED FONT DATA
символ заменяется двоичной строкой, состоящей из восьми строк, разделенных пробелами (четыре 14-байтовые строки и одна 13-байтовая, плюс три одиночных нулевых байта для пустых строк). Я специально разработал свой шрифт таким образом, чтобы упакованные данные не содержали пробелов, одинарных кавычек или обратной косой черты, чтобы их можно было кодироватьqw'...'
.Поскольку упакованная строка шрифта содержит непечатаемые символы, я предоставил настоящий скрипт в виде шестнадцатеричного дампа. Используйте,
xxd -r
чтобы превратить его обратно в исполняемый код Perl:Вот как это работает:
Первая строка (в версии де-golfed) считывает одну строку ввода, разбивает ее на массив символов (удобно , минуя какие - либо символ перевода строки) и отображает буквы ,
A
чтобыZ
и символы ,!
и.
для символьных кодов от 0 до 28, который обычно соответствуют непечатным управляющим символам в ASCII / Unicode. (Незначительным побочным эффектом этого является то, что любые вкладки на входе печатаются какJ
s.) Символ пробела остается не отображенным, поскольку цикл вывода в любом случае превращает любые коды выше 28 в пробелы.Вторая строка просто печатает заголовок PBM. Он использует
say
функцию Perl 5.10 , поэтому вам нужно запустить этот скрипт,perl -M5.010
чтобы он работал.Цикл вывода берет разделенный пробелами список упакованных строк изображения и присваивает каждой из них
$p
по очереди. (Я разработал шрифт так, чтобы упакованные данные не содержали никаких пробелов или'
символов.) Затем он зацикливается на вводимых символах@a
, используяvec
команду Perl, чтобы извлечь 4-битный фрагмент, соответствующий коду сопоставленного символа, из строки изображения, дополняет его до 8-битного байта и печатает его.Старый ответ, 268 байт:
Это быстрая и грязная первая попытка. Я украл шрифт PleaseStand и сжал его вместе с исходным кодом. Поскольку полученный скрипт в основном непечатаемый, вот hexdump; используйте,
xxd -r
чтобы превратить его в исполняемый код Perl:Распакованный код Perl состоит из следующей преамбулы:
следуют восемь повторений следующего кода:
с
BITMAP DATA HERE
заменой на 29 байт, кодирующих одну строку шрифта.источник
8086 машинный код
190 байт (122 байт с использованием BIOS)
Вот файл WinXP / MSDos .COM в кодировке Base64:
(Используйте что-то вроде этого ), чтобы декодировать текст и сохранить как «pbm.com». Затем в командной строке введите:
Я проверил это на своей машине WinXP, используя как стандартную командную строку, так и DosBox V0.74.
ОБНОВИТЬ
Эта версия имеет размер 190 байт и использует крошечный шрифт Ильмари Каронена (здесь нет доступа к BIOS!): -
источник
puts
в Ruby есть внешняя библиотека. Да, он использует биос шрифты, доступ к которым осуществляется через разыменование указателя (нетload
операции, чтобы получить шрифты в ОЗУ). Возможно, слишком далеко от правил. Мне бы это сошло с рук, если бы не было этих надоедливых детей ;-)Скрипт оболочки (код + данные = 295 символов)
Я надеюсь, что tail, gzip и dd не считаются «внешними библиотеками». Запустить как
echo -n 'YOUR TEXT HERE' | ./text.sh > out.pbm
. Я использовал шрифт Small Fonts size 7.5, хотя мне пришлось обрезать спусковое устройство от Q.Пример вывода
Код (137 символов)
Полный сценарий
(используйте
xxd -r
для воссоздания исходного файла)объяснение
od
стандартная утилита "восьмеричный дамп"-tu1
Опция говорит это , чтобы произвести десятичный дамп отдельных байт вместо (достаточного обходного пути для отсутствия BASh в КУСЕ (), Ord (), .charCodeAt () и т.д.)P4
является магическим числом для файла PBM двоичного формата, который упаковывает восемь пикселей в каждый байт (по сравнениюP1
с файлом PBM формата ASCII). Вы увидите, как это окажется полезным.dd
. (tail -2 $0
извлекает последние две строки скрипта; сжатые данные содержат один байт перевода строки 0x0a.) Так получилось, что восемь пикселей - это ширина одного символа. Нулевые байты, которые заполняют промежутки между поддерживаемыми символами, легко сжимаются, потому что они все одинаковы.wc -c
печатает имя входного файла «8» после подсчета байтов.источник
Python 2,
248247 байтИспользует шрифт 3x5, упакованный в печатаемую строку, 3 байта на символ. Шрифт хорошо читается, хотя n строчные, а v может быть ошибочно принято за au, если его не увидеть в контексте.
Фактический размер:
Увеличенный x3:
Выход представляет собой PBM типа P1, как в примере в задаче. Это было забавное испытание.
источник
Ruby 1,9, 346 байтов (122 кода + 224 байта данных)
Вот результат:
(Это хорошо, не правда ли?)
Шрифт сгенерирован
figlet -f banner -w 1000 $LETTERS
и этим скриптом .Беги с
echo -n 'CODEGOLF.STACKEXCHANGE.COM!' | ruby script.rb > image.pbm
.Скрипт генерирует все строки и просто печатает их.
Вот hexdump (использование
xxd -r
):При использовании goruby требуется 93 байта кода:
Использование ZLib обрезает размер данных до 142 байт вместо 224, но добавляет в код 43 байта, поэтому 307 байт:
Что дает в общей сложности 268 при использовании goruby:
источник
Java
862826:Здесь другой подход. Я думаю, что 'awt' не считается внешней библиотекой.
И безглым
Робот - это довольно любопытный способ Java вызвать getPixel. Я создаю метку с алфавитом и измеряю, где находится пиксель для каждой буквы.
В методе рисования,
int py = (y < 3) ? y : y +1;
и(8*a+x+17+x/4, py+81)
это сложный способ, чтобы отрегулировать положение в шрифте. Huuuh! иначе потребуется 9 строк, и на каждую 4-ю букву добавляется дополнительный пиксель по горизонтали. Метод проб и ошибок привел меня к этому решению.Затем в заголовок PBM записывается и каждая строка сообщения. Сообщение передается как заголовок фрейма.
Вот и все. Не самый короткий код, но ручная роспись шрифтов не требовалась.
Может быть, это может быть короче в BeanShell или Scala.
А теперь - как это выглядит?
Применено несколько масштабов:
Unzoomed:
Не то, чтобы число символов - это число символов в перетасованном решении Perl.
(немного больше в гольфе. Робот сделан статичным, что позволяет избежать одного объявления об исключении.)
источник
eog
(Глаз Гнома) и скриншот. Я загружу немасштабированнуюjpg
версию; возможно, ваш браузер использует интерполяцию ближайшего соседа :).С ++ СЛИШКОМ БОЛЬШОЙ, ЧТОБЫ ВЫИГРАТЬ
Я написал полнофункциональную программу рисования PPM на C ++ со своим собственным растровым шрифтом. Даже если убрать все ненужные функции, он все равно огромен по сравнению с ответами здесь из-за определения шрифта.
В любом случае, вот вывод для HELLO WORLD:
И код:
ppmdraw.h
ppmdraw.cpp
main.cpp
Makefile
Если вам интересно, полная библиотека PPMDraw находится здесь :
источник
SmileBASIC, 231 байт
Каждый персонаж содержит только 2 различных образца строки, выбранных из «палитры» из 8 комбинаций. Данные для каждого символа хранятся в 1 байте, а палитра хранится отдельно.
источник