Я подумал, что это будет интересным испытанием для всех, и мне любопытно увидеть решения, которые придут люди.
Распечатать текст "12 дней Рождества"
On the first day of Christmas,
my true love gave to me,
A partridge in a pear tree.
On the second day of Christmas,
my true love gave to me,
Two turtle doves,
And a partridge in a pear tree.
...
On the twelfth day of Christmas,
My true love gave to me,
Twelve drummers drumming,
Eleven pipers piping,
Ten lords-a-leaping,
Nine ladies dancing,
Eight maids-a-milking,
Seven swans-a-swimming,
Six geese-a-laying,
Five golden rings,
Four calling birds,
Three french hens,
Two turtle doves,
And a partridge in a pear tree.
правила
- Вам не нужно беспокоиться о капитализации; весь текст может быть без учета регистра
- Вы можете игнорировать любые знаки препинания: дефисы могут быть пробелами, а запятые и точки могут игнорироваться
- Между каждым стихом должна быть пустая строка
- Вы должны упорядочить свои номера: « первый день Рождества», « Четыре птицы по вызову» и т. Д.
Ответы:
Brainfuck - 2,974
Я довольно горжусь этим. Это звучит как довольно большое число, но имейте в виду, я не использовал никаких внешних библиотек сжатия, и ни один из оригинального текста нигде не находится в моей программе. Ни одно из других представлений не может сказать это. Это все вручную. Более наивные текстовые генераторы дают за этот текст более 39 тыс., Поэтому я бы сказал, что это значительное улучшение.
К сожалению, это примерно на 600 символов длиннее собственного вывода, но что угодно. Он хранит символы c, h, m, r, w в массиве и использует их для печати всего текста. Два массива справа от двенадцати пробелов каждый отслеживают, в какой день мы находимся для подсчета, и для каких элементов мы можем вывести. Возможно, я смогу немного оптимизировать его, реорганизовав карту памяти так, чтобы печатные символы помещались между двумя массивами подсчета, чтобы избежать таких длинных цепочек
<<<<<<<
и>>>>>>
, но на этом этапе было бы много работы. Я также мог бы, вероятно, выбрать некоторые более качественные начальные символы с частотным анализом, чтобы минимизировать приращение / уменьшение, но что угодно.Это зависит от правильной работы 8-битных упаковочных ячеек.
Ungolfed:
источник
Perl,
438291 символВдохновленный использованием Джеффом Берджесом сжатия DEFLATE , сжатого кода Ventero Ruby и использованием JB Lingua :: EN :: Numbers , мне удалось сжать мою запись до 291 символа (ну, в байтах), включая код распаковки. Поскольку программа содержит некоторые непечатаемые символы, я предоставил ее в формате MIME Base64 :
Чтобы отменить код программы, вы можете использовать следующий вспомогательный скрипт Perl:
Сохраните вывод в файле с именем
12days.pl
и запустите егоperl -M5.01 12days.pl
. Как уже отмечалось, для работы кода необходимо установить модуль Lingua :: EN :: Numbers .Если вам интересно, читаемая часть кода выглядит просто так:
где
...
обозначает 254 байта сжатого кода Perl RFC 1950 . Несжатый код имеет длину 361 символ и выглядит следующим образом:Написание этого кода было странным видом игры в гольф: оказывается, максимизация повторения и минимизация количества используемых различных символов гораздо важнее, чем минимизация необработанного числа символов, когда соответствующая метрика имеет размер после сжатия .
Чтобы выжать последние несколько символов, я написал простую программу, чтобы попробовать небольшие варианты этого кода, чтобы найти тот, который сжимает лучше всего. Для сжатия я использовал программу KZIP Кена Сильвермана , которая обычно дает лучшие коэффициенты сжатия (за счет скорости), чем стандартный Zlib, даже при максимальных настройках сжатия. Конечно, поскольку KZIP создает только ZIP-архивы, мне пришлось извлечь из архива необработанный поток DEFLATE и обернуть его в заголовок и контрольную сумму RFC 1950. Вот код, который я использовал для этого:
Если это похоже на ужасный клуг, то это потому, что это именно то, что есть.
Для исторического интереса вот мое оригинальное решение с 438 символами, которое генерирует более хороший вывод, включая разрывы строк и пунктуацию:
Основные моменты этой версии - пара регулярных выражений
s/e?t? .*/th/,s/vt/ft/
, которые строят порядковые числа от 4 до 12 из кардиналов в начале линий подарков.Этот код, конечно, также может быть сжат с использованием описанного выше трюка Zlib, но оказывается, что простое сжатие вывода более эффективно, в результате получается следующая 338-байтовая программа (опять же в формате Base64):
У меня также есть 312-байтовый gzip-архив текстов песен, созданный из того же потока DEFLATE. Я полагаю, вы могли бы назвать это «сценарием zcat». :)
источник
rings
с ,rGs
чтобы сохранить 2 символовG
наing,
, но оказывается, что добавление запятых позже действительно короче. Благодарность!$_
в моем обновлении ниже.Common Lisp, 333
363Встроенные средства для форматирования ординалов полезны, но большая часть сжатия происходит из-за возможности использовать один и тот же список аргументов снова и снова, пропуская все меньше и меньше аргументов при каждом запуске.
Как доказывает coredump в комментариях, встроенные средства все еще могут быть использованы для кардиналов.
источник
(dotimes(n 12)(format t"on-the-~:R-day-of-christmas my-true-love-gave-to-me ~v*~@{~R-~A ~#[AND-~]~}A-PARTRIDGE-IN-A-PEAR-TREE "(1+ n)(- 22 n n)12'drummers-drumming 11'pipers-piping 10'lords-a-leaping 9'ladies-dancing 8'maids-a-milking 7'swans-a-swimming 6'geese-a-laying 5'golden-rings 4'calling-birds 3'french-hens 2'turtle-doves))
JavaScript 570
Это мой первый раз в гольф. JavaScript 570
источник
Python 2,7 (465)
Тем не менее, я ставлю 'и' на той же строке, что и голуби, а не на куропатку.
источник
Рубин (474)
или в более читаемой форме (486):
Кто-нибудь получил идею, как обойти. обратный? я не мог придумать решение
источник
12.times
вместо(0..11).each
; делать одиночные путы с двумя аргументами вместо двух пут с одним аргументом; используйте запись% w () для массива дней Рождества. Наконец, вы можете избавиться от обратного, перевернув список, добавив дополнительный ^ в конец строки, а затем используя[-i..-1]
вместо [0..i].Perl,
500485Это моя первая попытка, и я уверен, что ее можно сделать намного короче. Разрывы строк предназначены для удобства чтения. Он имеет три важных массива, один из которых содержит название для каждого дня
@s
, один из которых перечисляет все дары (кроме первого)@a
, а другой - список подарков, которые уже были вручены@b
. Основной механизм заключается в том, что каждый день он печатает,@b
а затем передает один дополнительный подарок из@a
в@b
.Спасибо Андрею за 500-> 485
источник
rings
на,r$1s
чтобы сохранить еще 1 символs
как часть имени переменной, а переменная$is
не существует. (Они на самом деле я, а не один, кстати)eigth
->eighth
$i
, скажем,$;
чтобы обойти это. В$;
любом случае, никто не использует его по назначению.Vim - 578 нажатий клавиш
Я решил попробовать vim-golf это, так как это то, что может быть vim-golf.
Начните с вставки фреймворка - строка «X day of Christmas» в общей сложности 12 раз (89 нажатий клавиш):
Затем выполните серию макросов, которые будут вставлять числа от 2 до 12 в соответствующие места, где они должны быть для лирики (172 нажатия клавиш):
«Dw» во второй строке означает избавление от первого «и», потому что оно не идет туда.
Затем выполните серию замен для числа вещей, которые дала истинная любовь (319 нажатий клавиш):
И, наконец, заменяя каждое вхождение
X
порядковым номером:И мы сделали!
Я уверен, что есть другие оптимизации, которые я пропустил, но я думаю, что это довольно хорошо.
источник
:%s/2/two turtle doves,
С (644)
Количество не включает пробелы, используемые для представления.
Вывод как:
источник
Powershell,
487453Спасибо Даану за идею разбить составную строку.
Первоначально я включил оператор переключения, чтобы получить "и" на куропатку для всех, кроме первого стиха. Но поскольку этот вопрос освобождает нас от пунктуации, мы можем просто добавить «и» к голубям.
Это приводит к переводу строки следующим образом:
источник
Perl, 368
389(без юникода / сжатия)Использует Lingua :: EN :: Numbers , хотя я не уверен на 100%, что это хорошая идея, когда я вижу длину модуля и его идентификатора. Требуется Perl 5.10 или более поздняя версия, запускаемая из командной строки с помощью
-E
переключателя.Изменить: незначительные улучшения: прекратить использование массива, лучшее использование
$_
, ненужные пробелы.источник
PowerShell, 440
Это печатает текст, как указано в вопросе, с несколькими строками на стих. Мы можем сохранить несколько символов, если этого требования нет.
источник
C # (528)
источник
Ява, 2062
Я знаю, что это было опубликовано некоторое время назад, но я думал, что попробую. Я студент и все еще новичок в этом, но это, кажется, работает.
источник
Свифт, 577
Вы можете вставить это на детской площадке.
Я попытался переместить
v
в команду печати и получил:источник
Ruby 1.9.3, сжатый, 321 символ
Поскольку код содержит непечатаемые символы, вместо этого я опубликую hexdump кода:
Чтобы создать реальный код из hexdump, поместите его в файл и запустите
xxd -r hexdump > 12days.rb
. Затем выполнениеruby1.9.3 12.days.rb
запустит код и напечатает текст песни. Обратите внимание, что этот код требует Ruby 1.9.3 (потому что он используетZlib.inflate
), поэтому он не будет работать с Ruby 1.8.x, 1.9.1 и 1.9.2.Несжатый код длиной 425 символов:
источник
Perl, 319/313
Идея: распаковать и оценить решение JB's Lingua :: EN :: Numbers.
Сначала вставьте этот текстовый блок в команду
perl -e 'use MIME::Base64; print decode_base64 $_ while <>;' >12days.pl
. Далее запустите командуperl -M5.01 12days.pl
.Сам сценарий принимает форму, в
use Compress::Zlib;$_='...';eval uncompress$_;
которой...
находится решение JB 368 char после сжатия этой командой и экранирования a'
.Скрипт Илмари жалуется на изменение значения только для чтения без лишних
$_=...;
символов, но, вероятно, он сделает это 313 . Вы можете сэкономить еще несколько байтов, настроив сжатие вручную, как это делал Илмари, возможно, достигнув 310 или около того , но я не стал беспокоиться.Perl, 376 (обманывает другое представление) [мое первоначальное представление]
Во-первых, создайте скрипт на Perl,
12days.pl
содержащий:Затем перенаправьте вывод из любой другой отправки
12days.txt
и выполните команду:Vola
12days.pl
составляет около 376 байт и печатает песню. ;) Забавно с использованием rawinflate перемещает ровно шесть байтов из документа данных в код, начиная с вывода Ильмари.Первоначально я начал искать модуль кодирования Хаффмана напрямую, что не так уж нечестно. Тем не менее, к сожалению, CPAN не имеет модулей с таблицей энтропии букв английского алфавита, что вам действительно нужно при сжатии очень коротких строк.
Я обнаружил, что это
fortune -m Days\ of\ Christmas
тоже не работает, к сожалению.источник
PHP, 548
Уменьшенная длина со сжатием, 502
источник
ВАЛА,
584, 574Нет больше предупреждений при компиляции.
источник
Ява, 608
Первый пост на Stack Exchange, вторая попытка решить эту проблему.
Для таких задач Java немного громоздка, но использование split помогло снизить накладные расходы String.
источник
/// , 439 байт
Попробуйте онлайн!
Если разрешены завершающие символы новой строки, вы можете сохранить четыре байта:
Попробуйте онлайн!
объяснение
/// - это язык, где единственной операцией является самоизменяющаяся подстановка. В частности, команда
/abc/xyz/
заменяет все экземплярыabc
сxyz
в остальной части исходного кода, включая другие замены. Любые другие символы просто выводятся в STDOUT.Хотя этого достаточно для полноты по Тьюрингу, игра в гольф ///, как правило, состоит из начала с намеченного вывода и определения повторяющихся подстрок, которые можно заменить односимвольными сочетаниями клавиш.
\
может использоваться в качестве escape-символа в шаблонах, заменах и литеральных символах для обозначения литерала/
или\
.Первая команда встречается это
/|/\/\//
. Это означает , что «заменить все|
с//
в остальной части программы.» Это сохраняет байт для каждой последующей замены в программе.После этого делается набор замен для сжатия самого текста:
on the
становится^
.day of christmas \n my true love gave to me \n
становится%
.-a-
становится=
.ing
становится&
.even
становится*
.th%
становится+
.^
предшествует две новые строки (который появляется в каждом стихе, кроме первого) становится:
.После этого мы сами пишем текст. Это делается с помощью замен
A
черезK
. Каждая замена буквы добавляет строку к замене после нее. Например,K
представляетa partridge in a pear tree
иJ
представляетtwo turtle doves \n and K
.Таким образом, каждый стих песни состоит из:
^
или:
el*th
)%
A
черезK
это представляет правильную лирику.Однако, поскольку большинство ординалов заканчивается
th
, мы используем подстановкуth%
→,+
чтобы сохранить несколько байтов.источник
Бывают моменты, когда самое очевидное решение - самое короткое, то есть я больше не могу сопротивляться этому побуждению.
Bash на Mac OS X, 26
Perl, 111
Одна новая строка добавлена для удобства чтения.
источник
eval compress
трюк, чтобы утверждать, что нашел регулярное выражение, которое действительно хорошо сжимается, но раздувается до 200 символов. лолJava - 1329 символов
Мне лень это разглашать, но это здесь: http://ideone.com/MU9IcP .
источник
ПРОСТО , 1 байт
Замечания :
Язык был разработан после испытания и до сих пор WIP.
Как :
Любой символ выведет 12 дней Рождества.
источник