Ребму : 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."}
Це дозволить мені створити узагальнене рішення, яке може працювати без зусиль у будь-якій програмі, яка не використовує послідовності втечі. Версія 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}}
(Примітка. Хоча ця схема не працюватиме без налаштування програм, які використовують символи втечі, це не є фатальним недоліком. Отримати неперевершену ліву дужку в рядку, розділеній дужками, потрібно щось на зразок {Foo ^{ Bar}
..., але ви можете легко переписати це за допомогою альтернативне позначення рядків "Foo { Bar"
і комбіновані випадки можна керувати склеюванням суміші нерозміщених рядків.)
Отже ... як щодо прикладу? Як тільки загальна форма була доступна, ця програма 573 символів була зібрана всього за пару хвилин із трьох попередніх рішень для коду для гольфу:
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 {{BrdSz [sn [{N sbeo [tIt0l1eV} 0e5gXN1 01L {5s0} C {1} 0 {0 Do5f0 0bMe1e0r0} 0]]] tMw9C9 Numz Jl [paN + [KperlCJBn [[ba sWS {B noJn a] N a nn] {K, j} b P {. } lf EZ - - n [N m {G otothestoreandbuysome more}] {T akeonedownandpassitar 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.
Ось що робить код непарних символів, пробіл знову коригується:
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
друк у кожній половині програми. Але ми можемо зробити ще один трюк, просто повторно скориставшись рядковим рядком. У половині програм все ще визначено DO нормально, тому ми також могли просто сказати:
ddoo{{pp{{[RReebdo]l}}}}
Маючи в усьому випадку єдину частину, яку підбирає парсер, це символічне слово ddoo
і рядковий буквал, ми можемо переплутати будь-які дві програми, які ми бажаємо всередині цього рядкового буквального, і не гнівати парсера. Вдвічі зменшені версії просто скажуть:
do{p{Rebol}}
..і ...
do{p{[Red]}}
Як я кажу, ця частина виглядає звичною для інших рішень, які розглядають програми як рядки та їх вирівнюють. Але у випадку змагань, коли програми, які ви упаковуєте, містять вкладені рядки, які кидають ключі для них. Тут єдині речі, які можуть зіткнутися з вами, - це використання втечі через догляд ( ^
) ... який можна легко обійти.
(Невелика примітка "обману": Я додав QT для "QUIT" у відповідь на цю проблему. Насправді я раніше цілеспрямовано видалив абревіатуру для виходу з ладу ... тому що я якось вважав, що це корисно лише для використання консолі та просто зайняття двобуквенний пробіл, якщо його не було у відповіді. Я додаю його, тому що я бачу, що я помилявся, не додаючи його саме для цього випадку. Тим не менш, до цього зміни було б більше двох символів. Також, коли я вперше опублікував рішення, в Rebmu з’явилася помилка, яка не дозволила йому працювати фактично, хоча він і мав би ... зараз він працює.)
x0=00;;
. Великий виклик!