Напишите программу, которая печатает следующую строку из 80 символов:
Эта программа из codegolf.stackexchange.com переставляет себя для кодирования строки.
затем принимает одну строку ввода, затем печатает свой исходный код с возможными переупорядоченными точками кода (ни один не добавлен и ни один не удален). Когда этот код выполняется, то же самое должно произойти, за исключением того, что напечатанная строка будет самой последней строкой ввода.
Регулярное выражение в стиле Perl ^[A-Za-z0-9. ]{80}$
будет соответствовать любой строке ввода. Вы не можете делать никаких дополнительных предположений.
Оценка представления - это количество кодовых точек в исходном коде за вычетом 94 . Ниже - лучше.
Код не должен делать ничего, что было бы неприемлемо в квине ( например, чтение файла). В частности, любая заявка с отрицательной оценкой должна быть обманом, как 93! менее 64 80 .
Добавлено 2014-04-21: Весь исходный код вашей программы должен быть правильно сформирован в кодировке символов, в которой вы подсчитываете кодовые точки. Например, вы не можете использовать 80 последовательных байтов в диапазоне конечных байтов UTF-8 (80..BF) и считать каждый как один символ U + FFFD REPLACEMENT CHARACTER (или, что еще хуже, вообще не кодовый пункт).
Кроме того, если кодирование допускает несколько способов кодирования кодовой точки ( например, SCSU ), ваша программа, а также все программы, которые она генерирует прямо или косвенно, должны использовать только одну из них (или, по крайней мере, все должны обрабатываться одинаково во всем коде). ).
Ответы:
GolfScript,
231162131Как это устроено
Мы начнем с выбора 94 различных символов, которые будут переставлены для кодирования строки. Любой 94 символа будет работать, но мы выбираем следующее для целей игры в гольф:
Давайте назовем массив этих символов «&».
Строка ввода всегда будет содержать 81 символ (включая LF). Все эти символы присутствуют в первых 65 символах «&». Это единственная причина выбора символов в верхних 128 байтах.
Мы заменяем каждый символ строки его индексом в «&», поэтому LF становится 0, пробел становится 1 и т. Д.
Мы рассматриваем 81 полученный номер цифрами одного базового 65 числа. Давайте назовем этот номер «N».
Теперь мы перечисляем все возможные перестановки «&» и извлекаем перестановку, соответствующую числу сверху. Это достигается следующим образом:
c = 1
иA = []
.N % c
кA
.N = N / c
иc = c + 1
.c < 95
, вернитесь к 2.i = 0
иs = ""
.&[A[i]]
, добавьте его к «s» и удалите его из «&».i = i + 1
.i < 94
вернуться к 6.Предположим, у нас есть кодовые блоки «E» и «D», которые кодируют и декодируют строку, как описано выше.
Теперь нам нужна оболочка для тех блоков кода, которая соответствует требованиям вопроса:
Это делает следующее:
{…}.~
определяет блок, дублирует его и выполняет вторую копию. Первая копия останется в стеке.\.$
заменяет закодированную строку на блок и создает копию закодированной строки с отсортированными символами.[{}/]:&;
преобразует строку сверху в массив, сохраняет ее в «&» и удаляет ее.D puts
декодирует закодированную строку и печатает результат'"#{`head -1`}"'~
читает одну строку ввода, выполняяhead -1
в оболочке.E "'".@+\+
кодирует строку, добавляет и добавляет одинарную кавычку.\'.~'
Меняет местами закодированную строку и блок и добавляет строку'.~'
.После того, как блок был выполнен, GolfScript печатает содержимое стека (закодированная строка, блок и
'.~'
) и завершает работу.«Е» можно определить следующим образом:
«D» можно определить следующим образом:
Финальный гольф:
Замените
\.$[{}/]:&;0&@
на,0@.$[{}/]:&\
чтобы сохранить два символа.Определите функцию
{;65base}:b
для сохранения одного символа.Удалите все пробелы, кроме конечного LF и LF в строке.
пример
источник
Perl,
14281099В нем 1193 символа ASCII (включая 960 переставленных двоичных цифр). 1193 - 94 = 1099
Мой первый дизайн
Прежде чем я получил предложение от Денниса перейти на двоичный код, моя программа переставила восьмеричные цифры.
Мой первый дизайн кодирует каждую строку в 160 восьмеричных цифрах, с 2 цифрами на символ. Эта кодировка имеет 100 8 = 64 различных символов. Восьмеричная система имеет 8 разных цифр. Программа должна иметь 160 копий каждой цифры, поэтому она переставляет 8 × 160 = 1280 цифр.
Я храню 160 цифр,
$s
а остальные 1120 цифр$t
. Я начинаю с программой , которая не является Куайн, но только печатаю присвоения$s
и$t
для следующего запуска. Это оно:(() = $s =~ /$_/g))
это присвоение пустому списку переменных. Я взял этот трюк из учебника по контексту в PerlMonks . Вызывает контекст списка в операторе сопоставления=~
. В скалярном контексте совпадение будет истинным или ложным, и мне понадобится цикл, подобный$i++ while ($s =~ /$_/g)
подсчету совпадений. В контексте списка$s =~ /$_/g
это список совпадений. Я поместил этот список в скалярный контекст вычитания, поэтому Perl считает элементы списка.Чтобы создать квайн, я беру форму
$_=q{print"\$_=q{$_};eval"};eval
из квин Perl в Rosetta Code . Это одна Назначает строкаq{...}
с ,$_
а затем звонитeval
, так что я могу иметь свой код в строке , а также запустить его. Моя программа становится Куайном , когда я обернуть мою треть до последних строк в$_=q{
и};eval
, и изменить мои последниеprint
кprint "\$s = '$s';\n\$t = '$t';\n\$_=q{$_};eval"
.Наконец, я играю в гольф, меняя первое назначение на
$t
комментарий и удалив лишние символы.В нем 1522 символа ASCII (включая 1280 восьмеричных восьмеричных цифр).
1522 - 94 = 1428
Переключатель на бинарный
В комментариях Деннис заметил, что 960 переставленных двоичных цифр будут меньше, чем 1280 восьмеричных цифр. Поэтому я составил число перестановочных цифр для каждой базы от 2 до 16.
Хотя база 8 является локальным минимумом, базы 2, 3 и 4 связаны для лучшей базы с 960 переставленными цифрами. Для кода гольф, база 2 лучше, потому что Perl имеет преобразования для базы 2.
Замена 1280 восьмеричных цифр на 960 двоичных цифр экономит 320 символов.
Переключение кода с восьмеричного на двоичный код стоит 8 символов:
oct
наoct'0b'.$_
расходы 7./../g
на/.{6}/g
расходы 2."%02o"
на "% 06b" `стоит 0.160
на480
стоимость 0.0..7
на0,1
сохранение 1.Я узнал некоторые советы по игре в гольф на Perl . Они сохраняют 14 символов:
'A'..'Z','a'..'z','0'..'9'
наA..Z,a..z,0..9
, используя голые слова и голые числа, сохраняет 12 символов."\n"
чтобы$/
сохранить 2 символа.Я сохраняю 3 символа, перемещая
#$t
комментарий в конец файла. Это удаляет символ новой строки, заканчивающий комментарий, и литерал\n
в квине.Эти изменения сохраняют в общей сложности 329 символов и уменьшают мой счет с 1428 до 1099.
источник