Rebmu : 79 символов ИЛИ (37 + длина (p1) + 2 * max (длина (p2), длина (p3)))
Сначала я дам 79-символьное решение, которое спрашивает, какие языки вы должны изучать? (энтропия 4.0, 30 букв не включая ?
) и предлагает вам рекомендации Ребола и [Красного] :
DD 11 DD :do dd {dd {p{Which languages must you learn?}qt}} pp{{[RReebdo]l}}
Доступная здесь уникальная тактика, отсутствующая на других языках, основана на использовании того факта, что фигурные скобки являются асимметричным разделителем строк, который может юридически вкладываться:
my-string: {"It's cool," said {Dr. Rebmu}, "for MANY reasons--like less escaping."}
Это позволило мне создать обобщенное решение, которое может легко работать с любой программой, которая не использует escape-последовательности. Версия из 79 символов была достаточно простой для быстрого доступа, но для правильного размещения произвольного исходного кода для программ p2 и p3 вам понадобится полный шаблон. Если бы мы использовали это, это было бы 87 символов:
DD 11 DD :do dd {dd {p{Which languages must you learn?}qt}} ddoo{{pp{{[RReebdo]l}}}}
Шаблон для использования этого общего вида является то , что если у вас есть три исходных текстов последовательных символов длины переменных (давайте использовать пример , как AAA
, BBBBB
, CCCCCCC
) вы можете кодировать их как - то вдоль линий:
DD 11 DD :do dd {dd {AAAqt}} ddoo{{BCBCBCBCBC C C}}
(Примечание. Хотя этот шаблон не будет работать без настройки программ, использующих escape-символы, это не является фатальным недостатком. Для получения непревзойденной левой фигурной скобки в строке, разделенной фигурными скобками, требуется что-то вроде {Foo ^{ Bar}
..., но вы можете легко переписать это, используя альтернативная нотация строк "Foo { Bar"
и комбинированные падежи могут управляться путем склеивания смеси неэкранированных строк.)
Итак ... как насчет примера? Как только общая форма стала доступна, эта 573-символьная программа была собрана всего за пару минут из 3 предыдущих решений для гольфа:
DD 11 DD: do dd {dd {rJ N 0% rN Wa1m2j S {\ x /} D00 Hc & [u [Ze? Wa Qs ~ rpKw [isEL00c [skQd2k] [eEV? KQ [tlQ]] pcSeg - b00 [ eZ 1 5] 3] prRJ [si ~ dSPscSqFHs] eZ 1 [s + dCa + wM2cNO]]] Va | [mpAp2j] prSI ~ w { } Ls2w Wl h01tiVsb01n -1 chRVs { } hLceVn01qt}} ddoo {brD [sn [{N sbeo [tIt0l1eV} 0e5gXN1 01L {5s0} C {1} 0 {0 Do5f0 0bMe1e0r0} 0]]] tMw9C9 Нумц Jl [paN + [KperlCJBn [[ba sWS {B noJnlw]] 00] 0 {K, j} b P {. } Если EZ - - n [N m {Магазин и покупает еще что-то}] {T akeonedown и passitar ound} c B w P lf]]}}
Если кто-то хочет попробовать написать эту программу на своем языке и думает, что может побить 573, дайте мне знать. Я дам вам большое количество репутации, если вы это сделаете - если предположить, что ваш язык не Rebmu, потому что я знаю, что эти программы не минимальны. :-)
То «расточительное» расстояние, которое вы получаете в конце, - это то, что происходит, когда p2 и p3 имеют несбалансированную длину. Но в этом случае все 3 программы имеют разный размер, поэтому для p2 / p3 не существует особой подходящей пары. (Я выбрал их, потому что не было никаких внешних данных в качестве входных данных, таких как лабиринт или что-то еще, а не то, что они были одинаковой длины. Хотя я мог бы написать новые программы, которые были бы более оптимальными, я потратил достаточно времени, и смысл был ты не нужно писать новые программы ...)
Как это работает
(Примечание: я начал с более «креативного» подхода, который был не таким обтекаемым, а более интересным. Я переместил его в запись в своем блоге. поскольку описание этого подхода уже давно.)
Ключевым моментом здесь является хитрость «eval code as a string», как и в некоторых других записях, у нее просто есть козырь асимметричного разделителя строк. Я начну с объяснения работы случая из 80 символов.
Вот «целая» программа, настраивающая пробел для удобства чтения этого случая:
DD 11 ; assign 11 to dd (about to overwrite again)
DD :do ; make dd a synonym for DO (a.k.a. "eval")
; eval a string as source code that ends with QUIT (QT)
dd {dd {p{Which languages must you learn?}qt}}
; we'll never get here, but whatever's here must be legally parseable
pp{{[RReebdo]l}}
Здесь мы заканчиваем установку DD в качестве синонима DO (он же «eval»). Но хитрость заключается в том, что когда запускаются пополам программы, они запускают код, единственным эффектом которого является определение D для безобидного литерала 1.
Вот что делает код odd-chars, пробелы снова корректируются:
D 1 ; assign 1 to d
D d ; assign d to itself, so it's still 1
d ; evaluates to integer, no side effect
{d pWihlnugsms o er?q} ; string literal, no side effect
p {Rebol} ; print "Rebol"
А вот код четных символов:
D 1 ; assign 1 to d
D:od ; URL-literal (foo:...), no side effect
d ; evaluates to integer, no side effect
{{hc agae utyulan}t} ; string literal (well-formed!), no side effect
p {[Red]} ; print "[Red]"
Это на самом деле так, что для не разделенной на две части программы dd {dd {(arbitrary code)qt}}
будет выполняться любой код, который вы хотите. Однако есть два вызова для оценки вместо одного. Дело в том, что хотя вложенные скобки прекрасно работают в чередующемся коде, они портят поведение DO. Потому что:
do {{print "Hello"}}
Будет загружать строку как программу, но эта программа в конечном итоге будет просто строковой константой {print "Hello"}
. Таким образом, хитрость, которую я здесь использую, заключается в том, чтобы взять мой DD (содержащий то же значение функции, что и DO) и запустить его дважды. Полуфабрикаты жуют разные части строки, но они не жуют оба, если четность / нечетность правильны для содержимого, и потому что то, что осталось вне строки после деления пополам, является просто интегральной константойd
они безвредны.
С этим шаблоном нетрудно написать поведение программы, когда оно не разрезано пополам - вы можете вставить что угодно, если длина кода четна (нечетно, если вы считаете QT, то есть QUIT). Если вам нужно получить четное число из нечетного, добавьте пробел (так что в моей формуле на самом деле есть +1 на p1 для нечетных длин программ p1) . Казалось бы, уловка заключается в том, чтобы впоследствии написать этот код с чередованием, который должен пройти синтаксический анализатор, если это не так. разделен пополам. (Он не будет запущен из-за QT, но он должен быть загружаемым, прежде чем он будет выполнен.)
Этот случай тривиален; pp
прекрасно загружается как символ, даже если он не определен, и разбивается на части p
для печати в каждой половине программы. Но мы можем сделать еще один трюк, просто снова используя строковый литерал. Половинные программы по-прежнему определены нормально, поэтому мы могли бы просто сказать:
ddoo{{pp{{[RReebdo]l}}}}
Имея единственную часть, подобранную синтаксическим анализатором во всем случае, быть символическим словом ddoo
и строковым литералом, мы можем затем чередовать любые две программы, которые мы хотим, внутри этого строкового литерала и не раздражать синтаксический анализатор. Половинные версии просто скажут:
do{p{Rebol}}
..а также...
do{p{[Red]}}
Как я уже сказал, эта часть выглядит знакомой другим решениям, которые рассматривают программы как строки и оценивают их. Но в случае соревнования, когда программы, которые вы упаковываете, содержат вложенные строки, это добавляет ключи для них. Здесь единственные вещи, которые доставят вам неприятности, - это использование выхода через carets ( ^
) ..., которое можно легко обойти.
(Небольшое «читерское» примечание: я добавил QT для «QUIT» в ответ на эту проблему. На самом деле, я целенаправленно удалил аббревиатуру для Quit раньше ... потому что почему-то я думал, что это хорошо только для консольного использования и просто взялся за двухбуквенный пробел, если его не было в REPL. Я добавляю его, потому что вижу, что был неправ, не добавляя его в этом конкретном случае. Тем не менее, до этого изменения он был бы на 2 символа длиннее. Когда я впервые опубликовал решение, в Rebmu была ошибка, которая не позволяла ему работать, хотя он должен был ... теперь это работает.)
x0=00;;
. Отличный вызов!