Напишите самую короткую программу, которая печатает всю лирику «Никогда не сдавайся» Рика Эстли.
Правила:
- Должен выводить текст в точности так, как он представлен в приведенном выше тексте *. Вот сырой дамп: http://pastebin.com/raw/wwvdjvEj
- Не может полагаться на какие-либо внешние ресурсы - все тексты должны быть сгенерированы / встроены в код.
- Не используйте существующие алгоритмы сжатия (например, gzip / bzip2), если вы не включите полный алгоритм в свой код.
- Используйте любой язык, самый короткий код выигрывает.
Обновление, 1 июня 2012 года:
для решений, содержащих текст не-ASCII, размер вашего решения будет учитываться в байтах на основе кодировки UTF-8. Если вы используете кодовые точки, которые не могут быть закодированы в UTF-8, ваше решение не будет считаться действительным.
Обновление, 7 июня 2012:
Спасибо всем за ваши потрясающие решения! Я приму кратчайший ответ завтра днем. Прямо сейчас, ответ GolfScript от Питера Тейлора выиграл, так что постарайтесь улучшить его, если хотите победить его! :)
* В Pastebin есть опечатка (строка 46 «знать» должна быть «известна»). Вы можете копировать его или нет по своему усмотрению.
code-golf
kolmogorov-complexity
многочлен
источник
источник
Ответы:
Ruby
576 557556 (552) символа && PHP 543 символаЕще одно решение поиска и замены. Обратите внимание , что эта форма решения по существу грамматики на основе сжатия кода http://en.wikipedia.org/wiki/Grammar-based_code Проверьте http://www.cs.washington.edu/education/courses/csep590a/07au /lectures/lecture05small.pdf для простого для понимания примера сжатия.
Я написал правила замены так, чтобы начальный символ для каждой замены вычислялся (они расположены в последовательном порядке ASCII); это не должно присутствовать в данных перехода.
замечания по реализации
старая реализация
Эта старая реализация имеет 576 символов и началась с правил подстановки из реализации ugoren bash / sed. Не обращая внимания на переименование переменной подстановки, мои первые 28 подстановок в точности совпадают с выполненными в программе Угорена. Я добавил еще несколько, чтобы уменьшить общее количество байтов. Это возможно, потому что мои правила представлены более эффективно, чем те, что реализованы Угореном.
Я не пытался оптимизировать правила замены в этом.
примечания к конкурсу
Схема декомпрессии поиска и замены хорошо работает в этом конкурсе, потому что большинство языков имеют встроенные процедуры, которые могут сделать это. С таким небольшим количеством текста, который будет сгенерирован, сложные схемы декомпрессии не кажутся реальными победителями.
Я использовал только текст ASCII, а также избегал использования непечатных символов ASCII. С этими ограничениями каждый символ в вашем коде может представлять максимум до 6,6 бит информации; это очень отличается от реальных методов сжатия, где вы используете все 8 бит. В некотором смысле, это не «справедливо» сравнивать с размером кода gzip / bzip2, потому что эти алгоритмы будут использовать все 8 бит. Более привлекательный алгоритм распаковки может быть возможен, если вы можете включить в свои строки традиционно непечатаемый ASCII, и каждый непечатаемый символ все еще записывается в вашем коде как один байт.
PHP решение
Приведенное выше решение берет PHP от «грустного парня» и объединяет его с моими правилами подстановки. Ответ PHP, оказывается, имеет самый короткий код распаковки. Смотрите http://ideone.com/XoW5t
источник
sed
решение, конечно, не может победить его. Я работаю над чем-то, что, я надеюсь, имеет шанс - у вас есть 75 байтов служебной информации, возможно, я уменьшу это (не в Ruby).Bash / Sed,
705650588582 символаЛогика :
основная идея - простая замена. Например, вместо того, чтобы
Never gonna give you up\nNever gonna let you down
писать, я пишуXgive you up\nXlet you down
и заменяю всеX
наNever gonna
.Это достигается путем запуска
sed
с набором правил в формеs/X/Never gonna /g
.Замены могут быть вложенными. Например,
Never gonna
это часто встречается, но так же иgonna
в других контекстах. Поэтому я могу использовать два правила:s/Y/ gonna/g
иs/X/NeverY/g
.При добавлении правил части текстов песен заменяются отдельными символами, поэтому они становятся короче. Правила становятся длиннее, но если заменяемая строка длинная и частая, это того стоит.
Следующим шагом является удаление повторения из самих
sed
команд. Последовательностьs/X/something/g
довольно повторяющаяся.Чтобы сделать его короче, я изменил команды sed, чтобы они выглядели так
Xsomething
. Затем я использую,sed
чтобы преобразовать это в обычнуюsed
команду. Кодsed 's#.#s/&/#;s#$#/g;#
делает это.Окончательный результат -
sed
команда, аргументы которой генерируются другойsed
командой в обратных кавычках.Более подробное объяснение вы можете найти по этой ссылке .
Код:
Примечания:
Механизм распаковки всего 40 символов. Другие 543 - это таблица перевода и сжатый текст.
bzip2
сжимает песню до 500 байт (без движка, конечно), поэтому должно быть место для улучшения (хотя я не понимаю, как бы я добавил кодировку Хаффмана или что-то вроде этого достаточно дешево).<<Q
(или<<_
) используется для чтения до заданного символа. Но конец сценария (или выражение обратной цитаты) достаточно хорош. Это иногда вызывает предупреждение.Более старое и простое решение, 666 символов:
источник
\0
с&
.&
это делает 5.Пробел - 33115 символов
StackExchange дал ответ на мой вопрос, вот источник: https://gist.github.com/lucaspiller/2852385
Не очень ... Я думаю, что я могу немного уменьшить его.
(Если вы не знаете, что такое Whitespace: http://en.wikipedia.org/wiki/Whitespace_(programming_language) )
источник
JavaScript,
590588 байтСлегка в зависимости от того, как строка «печатается».
https://gist.github.com/2864108
источник
if(g.indexOf(g[i])!=-1)
прежде чемe=
это исправить.with(f.split(g[i]))f=join(pop())
вfor..in
цикле сохраняет байтC #
879816789 символовПервая попытка CodeGolf, так что определенно не победитель, уверен, что он действителен, несмотря на свою злобность.
источник
var s1="a";var s2="b";
попробуйте использоватьstring s1="a",s2="b"
; если у вас есть 2+ объявления, это короче.!
и убрав его из других мест.Python,
597589 байтМожет быть возможно выжать еще пару байтов:
источник
BrainFuck - 9905
Уверен, я смогу немного поправиться, настроив его, но сейчас это довольно хорошо. Предполагая, что у вас нет проблем с тем, что он намного больше исходного текста.
источник
Scala, 613 байт
Это алгоритм декомпрессии текста, рекурсивно применяющий правило, в которое
~stuff~ blah ~ ~
следует преобразоватьstuff blah stuff stuff
(т. Е. Когда вы впервые видите незнакомую пару символов, он определяет, что копировать; после этого вы вводите значение, когда вы его видите).Примечание: в конце может быть дополнительный возврат каретки, в зависимости от того, как вы рассчитываете. Если это недопустимо, вы можете оставить последний в кавычке (сохраняя один символ) и изменить разделение на
split(" ",-1)
(тратя 3 символа) для 615 байтов.источник
N
повторений длиныL
вы используетеL+N+1
символы, а я используюL+N+2
. Но ваш декомпрессионный код составляет 102 символа, а мой - 40.589, C (только библиотечная функция - putchar)
Таблица правил подстановки, где символы в диапазоне -.._ (45..90) указывают, какое правило применять, таким образом, некоторые 48 правил (45, c-45> U48 в коде), другие символы должны быть напечатаны
правила ограничены символом «&» (38 в коде, n уменьшается до нуля и, следовательно, s указывает на правильное правило)
Правило 0 указывает, что следующий символ должен быть заглавным (установив k = 32 в коде), это освобождает больше места, чтобы добавить больший непрерывный диапазон символов для правил
main (..) вызывается с 1 (в соответствии с нулевым аргументом программного соглашения C), и, таким образом, правило 1 является корневым правилом.
Эволюция кода
побрил еще 9 байтов благодаря предложению Угорена
сбрил еще 36 байтов, создавая таблицу алгоритмически, а не вручную и с помощью подсказки ""
срезал еще 15 байтов, изменив таблицу из символа * [] в одну строку, где '&' разделяет части
побрил еще 19 байт благодаря большему количеству советов от угорена
уменьшив 31 байт, добавив больше правил, сделал специальное правило для заглавных букв, тем самым предоставив больше места для индексов правил.
побрил 10 байтов благодаря еще большему количеству советов от Ургорена и немного подправил правила
источник
*p>>4^3?putchar(*p):e(r[*p-48])
"\'"
перевод не нужен."We're"
является допустимой строкой.ing
лучший кандидат.d(int n)
->d(n)
. Изменить*s=='~'
на*s-'~' and reverse the
?:, also saving parenthesis around
! N? ..: 0. Using 126 instead of
'~' `бесполезно, но почему~
?main
рекурсивным. Первоначальный вызовmain(1)
вместоd(0)
, но он может иметь дело с (возможно , ведущим~
вs
). Также лучшей альтернативой~
является вкладка (ascii 9 - однозначная цифра).Perl,
724714883 байтаТаким образом, изменение правил, запрещающих использование Latin-1, убило мое решение. Это достаточно другой подход, который я ненавижу просто удалять, так что вот ограниченная версия, которая использует только 7-битный ASCII, согласно новым правилам, с огромным увеличением размера.
Конечно, управляющие символы здесь все еще искажены, поэтому вы все равно захотите использовать base64-кодировку:
Поскольку я думаю, что он все еще должен быть видимым, несмотря на то, что он DQ'd, вот оригинальное решение:
Base64-кодировка скрипта:
источник
Python
781731605579 символовЕсть намного больше и гораздо лучших ответов, когда я впервые увидел это, но я потратил много времени на свой скрипт на Python, поэтому я собираюсь опубликовать его любым способом, было бы здорово увидеть предложения по его дальнейшему сокращению,
Редактировать: благодаря предложениям Эда Х 2 расколотых символа, чтобы пойти дальше, мне, возможно, придется реструктурировать много вещей здесь, что займет некоторое время
После того, как я вручную создал строку (очень утомительно), я написал функцию для рекурсивного поиска замены шаблона, которая была наиболее прибыльной (на этом этапе), которая дала мне решение, но оказалось, что размер увеличился на 10. символы.
Итак, я сделал свой алгоритм немного менее жадным, вместо того чтобы делать окончательное ранжирование только по «уменьшенным символам», ранжированию по функции «уменьшенных символов», «длины шаблона» и «количества шаблонов»
длина шаблона = длина счета = количество
Тогда я спросил мой бедный ноутбук бежать бесконечно, назначая случайные значения
lengthWeight
иcountWeight
и получить различные конечные размеры сжатия и хранения данных для минимальных размеров сжатия в файлеПримерно через полчаса он получил указанную выше строку (я попытался еще поработать с ней, чтобы посмотреть, смогу ли я сократить код), и она не опустится ниже, я думаю, что я что-то здесь упустил.
вот мой код для него, также
max_pattern
очень медленный (Примечание: код выдает строку, похожую на форму в моей предыдущей версии решения, я вручную обработал ее, чтобы получить текущую форму, вручную, я имею в виду, вручную в оболочке Python)источник
\n
будет стоить 5 символов и сэкономить 9. 2. Дополнительное пространство вin (g,l..)
. 3.join(..)
работает так же как иjoin([..])
(как минимум в 2.7).Malbolge, 12735 байт
Попробуйте онлайн.
Создано с использованием инструментов здесь.
источник
JavaScript 666 байт
Вдохновленный решением tkazec .
Посмотрите на пост в блоге, который я написал об этом, он содержит все источники и объясняет, как я создал этот код.
Вы можете скопировать и вставить код в консоль вашего браузера. Или попробуйте это на http://jsfiddle.net/eikes/Sws4g/1/
источник
Perl,
584578577576575571564554553540Это решение следует тому же основному подходу, что и большинство других: при заданной исходной строке выполняйте повторные замены повторяющихся частей текста.
Правила замещения задаются одним символом, предпочтительно тем, который не встречается в выходном тексте, поэтому правило длины L и встречающееся N раз сохранит приблизительно N * LNL-1 (N * L - исходная длина всех вхождений, но символ подстановки встречается N раз, а сам текст литерала имеет длину L, а правила разделяются разделяющим символом.) Если символы подстановки указаны явно, экономия сокращается до N * LNL-2. Учитывая, что большинство языков могут вычислять символ с помощью chr () или аналогичного короткого кода, первый подход имеет тенденцию быть лучше.
Существуют некоторые недостатки в вычислении символа подстановки, наиболее существенным из которых является необходимость непрерывного диапазона символов ASCII. В выводе используются в основном строчные буквы, но достаточно заглавных букв и знаков препинания, чтобы потребовать либо замены символа на себя, либо переназначения нескольких символов на этапе исправления впоследствии, либо упорядочения правил так, чтобы замены проблемными символами происходили раньше. Использование языка, который заменяет использование регулярных выражений, также означает, что для символов, которые имеют особое значение в регулярном выражении, есть ошибки.
.
+
*
\
?
Мой оригинальный подход имел 63 байта в декодере и 521 в правилах. Я потратил много времени на оптимизацию правил, что может быть сложно, особенно с короткими правилами, поскольку они могут перекрываться. Я расширил декодирование до 55 байт, а правила - до 485, немного обманув формулу. Обычно правило из 2 символов, которое встречается 3 раза, или правило из 3 символов, которое встречается дважды, на самом деле не спасет никакой длины, но есть лазейка - которая также позволяет составлять слова, которые не являются частью вывода; ).
Я использую управляющие символы в этом решении, поэтому решение здесь представлено в кодировке base64.
И здесь это немного более читаемая (но менее исполняемая) версия.
Тем не менее, я подозреваю, что это все еще не минимум, поскольку Эд Х. указывает, что декодирование php является самым коротким при 44 байтах, и я видел возможности для улучшения правил, которые он использует. У меня есть 52-байтовый декодер в Perl, но я не смог использовать его для этого решения, так как мне нужно было пройти через диапазон в обратном порядке.
источник
PHP
730707 символовисточник
$s="Never gonna give...
можно сократить с$n
.Perl -
589 588 583 579576 байтКаждое правило состоит из 1 буквы, тела и подчеркивания. Пока правила могут быть отрублены с самого начала, заголовок правила заменяется его телом в остальной части текста. Дается заголовок первого правила, заголовки всех следующих правил генерируются из переменной $ i.
Так как заголовок для следующего правила помещается в начале текста по предыдущему правилу, последнее правило создаст символ, который больше не будет удален. Я должен был выбрать диапазон имен, где последним будет «W», чтобы я мог удалить оригинальную букву «W» в начале текста и заменить ее заменой правила.
Кодирование было выполнено скриптом Python с использованием простого алгоритма горного подъема.
Вот код Perl:
(Я нахожу замечательным, что сжатый текст содержит «listenBach»: D)
И вот код Python, который его генерирует:
источник
while
для цикла; это позволяет вам отказаться от скобок и скобок. Другая идея: выяснить, как использоватьsay
вместо того,print
чтобы делать вывод.Python 2,7,
975803 байтаНе самое лучшее - я (сейчас) хотел бы, чтобы Python делал расширения форматирования подобным образом. Увы, это не так.
Изменить: Имитация расширения с альтернативным синтаксисом форматирования (вроде ..)
источник
Clojure
720 байтов / символов:
(Воспроизводится здесь с дополнительными пробелами, чтобы вы могли видеть форматирование)
источник
C # - 605 символов | T-SQL - 795 символов | C # - 732 символа | C # - 659 символов
Источником вдохновения для этого послужил пример sed. Единственное существенное изменение, которое я сделал, - это последовательный поиск символов ASCII, поэтому их не нужно было объявлять. К сожалению, это C #, поэтому я не знаю, как сделать его меньше. Я взял тот же текст замены и сделал код в T-SQL, используя временную таблицу.
T-SQL
C # - Вторая попытка Это была попытка другого подхода. Сжатие было полностью выполнено компьютером, ищущим лучшие замены. Поиск выполняется последовательно и упорядочен по размеру, поэтому нет необходимости в поиске с разделителями, однако код для выполнения поиска оказался менее эффективным, чем я думал, поэтому в итоге он стоил на 127 символов больше! Живи и учись.
3-я попытка на C #. На этот раз у меня кончились символы \ b, \ r, \ t. Вы можете использовать \ rN \ n, чтобы заменить первый символ в строке на заглавную N, но на самом деле он не сохранил символы. Я создал псевдонимы \ b, чтобы переместить курсор назад и затем написать поверх существующего текста. Но ничто из этого не сэкономило места, и в конце концов я оказался в еще худшем положении, чем простая стратегия поиска и замены.
источник
REPLACE
подход, особенно с динамическим SQL, но есть еще много способов использовать это: использовать@
в качестве переменной вместо@s
, сделать ее постоянной таблицейt
вместо#t
(вам не нужно убирать за собой), избавьтесь от 29-символьного оператора COLLATE и просто потребуйте, чтобы он выполнялся на сервере / базе данных с правильным сопоставлением, использованиемvarchar(999)
илиvarchar(max)
множеством ненужных пробелов вокруг знаков равенства и запятых и т. д.PHP,
591585568564 байтаисточник
Рубин, 1014 байт
Я только учусь программированию, поэтому я не собираюсь здесь побивать рекорды. Но это было забавное задание.
источник
GolfScript (511 байт)
Это использует изменение базы для упаковки битов, поэтому оно включает символы, которых нет в ASCII. Однако нецелесообразно оценивать эти символы по их кодировке UTF-8, потому что интерпретатор воспринимает программу как ISO-8859-1. По этой причине я указал длину в байтах, а не в символах.
Base-64 кодируется:
Шестнадцатеричный дамп (вывод из
xxd
):Как и большинство лучших решений, здесь используется подход, основанный на грамматике, с разбивкой строк и объединениями для расширения грамматики. Грамматика имеет 30 правил и была найдена путем жадного поиска.
источник
JavaScript, 854 символа (добавлены новые строки для «читабельности»)
источник
Наивный ш / эхо - 810 байт
источник
JavaScript 789 символов
Мой JavaScript (печатает с «document.write ()»):
Я заменяю некоторые общие слова и фразы кириллическими буквами, а затем меняю их обратно с помощью функции replace ().
После того, как я сократил текст, я сократил свою программу тем же методом и выполнил код с помощью eval ().
источник
Рубин,
741678657627619 байтЭто итеративное расширение символа. Для каждого из 28 символов строки в первом аргументе
gsub!
все вхождения этого символа в_
заменяются соответствующим разделом второй строки (разделенным+
символами).источник
Питон, 573 символа
Мое
sed
решение не пойдет дальше, и его избили несколько человек, поэтому я выбрал новый подход.К сожалению, это достаточно хорошо для
2-го3-го места (на данный момент) - Эд Х. все еще намного впереди меня .Примечания :
Основная идея была заимствована у Эда Х. - использование последовательных символов для замены вместо указания их в каждом правиле замены.
Мой способ иметь дело с персонажами, присутствующими в песне
, отличается от Ed- я просто перевожу каждого из них себе (и если за ним всегда следует что-то, добавьте его, который работал только дляW
).Код генерируется скриптом, который ищет хорошие переводы. Сначала я использовал жадный алгоритм, который просто выбирает тот, который дает наилучшее сокращение. Затем я обнаружил, что настройка его на более длинные строки немного улучшает его. Я думаю, это все еще не оптимально.
источник
Golfscript,
708702699691 байтисточник
" I'm feeling":i;
?j
, я назначил три сцепленных строки (удаленных{
и}
добавленных++
для объединения). Это позволило мне объявитьi
inline при составлении содержимогоj
.g
строку в и для хора, используя одну строку с новыми строками, а затемn/g*
g
поскольку это также используется к концу (фактически возможно, но стоило бы еще 1 символ в конце). Тем не менее, подход split / fold для вставки g в начале каждой строки является отличным средством сохранения символов.Java, 858 байт
Ух ты. Я действительно не думал, что смогу сжать это так сильно.
Ungolfedв удобочитаемой форме:источник
String foo; String bar;
ухудшает читабельность, поэтому я сделал их, как когда-то не в гольф.JavaScript,
1428,1451,883 * символовОпределенно не самое короткое решение, но оно здесь.
Логика решения довольно проста:
* Конечно, решение становится намного короче, если брать уникальные строки вместо уникальных слов.
источник