7 , 410 символів, 154 байти в кодуванні 7, 0 літер = оцінка 154
55104010504200144434451510201304004220120504005434473340353241135014335450302052254241052253052244241052335452241114014241310052340435303052335442302052335500302052335430302052313340435303135014243241310335514052312241341351052302245341351525755102440304030434030421030442030424030455733413512410523142410523030523112411350143355142410523414252410523102410523002410523413342411145257551220304010420030455741403
Спробуйте в Інтернеті!
У виклику, який не любить використання букв, яку кращу мову використовувати, ніж мову, що складається лише з цифр?
Це повноцінна програма, яка виходить із збоїв, тому сторонній вихід у stderr є, але stdout є правильним.
Пояснення
Програма 7 на першій ітерації просто натискає на стек декілька елементів (адже з 12 команд, що існують у 7, лише 8 з них можуть бути представлені у вихідній програмі, а ті 8 спеціалізовані для написання коду для виштовхування певних структур даних до стеку). Ця програма не використовує 6
команду (що є найпростішим способом створення вкладених структур, але в іншому випадку має тенденцію не відображатися буквально у вихідній програмі), тому це 7
визначають структуру лише команди; 7
висуває новий порожній елемент у верхню частину стека (тоді як команди 0
… 5
просто додаються до верхньої частини стека). Таким чином, ми можемо додати пробіли до програми, щоб показати її структуру:
551040105042001444344515102013040042201205040054344 7
33403532411350143354503020522542410522530522442410523354522411140142413100523
40435303052335442302052335500302052335430302052313340435303135014243241310335
514052312241341351052302245341351525 7
55102440304030434030421030442030424030455 7
33413512410523142410523030523112411350143355142410523414252410523102410523002
41052341334241114525 7
551220304010420030455 7
41403
Елементи в кінці програми висуваються останніми, тому знаходяться на вершині стека на початку другої ітерації. Після цієї ітерації та всіх майбутніх ітерацій інтерпретатор 7 автоматично робить копію верхньої частини стека та інтерпретує її як програму. Літерал 41403
підштовхує (нелітеральний, живий код) 47463
(7 має 12 команд, але лише 8 з них мають імена; як такий, я використовую жирний шрифт для показу коду, а нежирний - для того, щоб показати літерал, який генерує цей код, тобто це, наприклад 4
, команда, яка додається 4
до верхнього елемента стека). Отже програма, яка працює на другій ітерації 47463
. Ось що це робить:
47463
4 Замініть два верхні елементи стека, додайте порожній елемент між
7 Додайте порожній елемент стека у верхню частину стека
4 Помініть двома елементами стека на вершині стека, Додайте порожній елемент між
6 Опрацюйте, які команди створювали б верхній елемент стека;
додайте це до елемента внизу (і виведіть стару верхівку стека)
3 Виведіть верхній елемент стека, викладіть елемент нижче
Це легше зрозуміти, якщо ми подивимось, що відбувається зі стеком:
- ... d Ĉ б а
47463
(код для запуску: 47463
)
- ... d з б спорожнити а (код для запуску: )
47463
7463
- ... d з б спорожнити в порожній (код для запуску: )
47463
463
- ... d з б порожній порожній порожній а (код для запуску: )
47463
63
- ... d з б порожній порожній « в » (код для запуску: )
47463
3
- … D c b порожній (код для запуску: порожній )
47463
Іншими словами, ми беремо верхню частину стека a , опрацьовуємо, який код, швидше за все, його створив, і виводимо цей код. 7 інтерпретатор автоматично вискакує порожні елементи з верхньої частини стека в кінці ітерації, тому ми закінчуємо 47463
спинку вгорі стека, як і в оригінальній програмі. Слід легко зрозуміти, що буде далі: ми закінчуємо перебирання кожного елемента стека один за одним, виводячи їх усі, поки стек не переллється і програма не руйнується. Таким чином, ми в основному створили простий цикл виводу, який дивиться на вихідний код програми, щоб визначити, що виводити (ми не виводимо структури даних, які були натиснуті на стек нашими 0
...5
команди, ми замість цього відтворюємо, які команди використовувались, переглядаючи, які структури створені, і виводити їх). Таким чином, перший фрагмент виведення даних є 551220304010420030455
(вихідний код, який генерує другий елемент зверху стека), другий - 3341351…114525
вихідний код, що генерує третій з верхнього елемента стека) тощо.
Очевидно, однак, ці фрагменти вихідного коду не виводяться некодованими. 7 містить кілька різних доменних мов для кодування виводу; Після вибору мови, що залежить від домену, вона залишається у використанні до явного очищення, але якщо жодна з мов ще не була обрана, перша цифра коду, що виводиться, визначає, яку з мов використовувати. У цій програмі використовуються лише дві мови: 551
і 3
.
551
досить простий: це, в основному, старий код Бодо / телетип, який використовується для передачі букв по телетипах, як 5-бітний набір символів, але модифікований, щоб зробити всі літери малими літерами. Отже, перший фрагмент коду для виведення декодується таким чином:
551 22 03 04 01 04 20 03 04 55
c a SP e SP n a SP reset output format
Як видно, ми вписуємо кожен символ у дві восьми цифри, що є досить пристойним коефіцієнтом стиснення. Пари цифр у діапазоні 0-5 дають нам 36 можливостей, на відміну від 32 можливостей, які потребують Бодо, тому інші чотири використовуються для спеціальних команд; в цьому випадку, 55
наприкінці очищається запам'ятовується вихідний формат, дозволяючи нам використовувати інший формат для наступного виробу, який ми виробляємо.
3
концептуально ще простіше, але з поворотом. Основна ідея - взяти групи з трьох цифр (знову ж таки, в діапазоні 0-5, оскільки це ті цифри, для яких ми можемо гарантувати, що ми зможемо відтворити вихідний вихідний код з його виводу), інтерпретувати їх як тризначні число в базі 6, і просто виводимо його як байт у двійковій формі (таким чином дозволяючи нам виводити багатобайтові символи на потрібний вихід просто шляхом виведення декількох байт). Поворот, однак, пов'язаний з тим, що в базі 6 є лише 216 трицифрових чисел (з можливими провідними нулями), але 256 можливих байтів. 7 обходить це шляхом з'єднання чисел від 332₆ = 128₁₀ вгору до двох різних байтів; 332
може виводити або байт 128 або 192, 333
або байт 129 або 193 тощо, до 515
якого виводить або байт 191, або 255.
Як програма знає, яку з двох можливостей вивести? Можна використовувати трійки цифр 520
вгору, щоб це чітко контролювати, але в цій програмі нам не потрібно: 7 за замовчуванням - це вибрати всі неоднозначні байти таким чином, щоб вихід був дійсним UTF-8! Виявляється, завжди існує максимум один спосіб зробити це, доки ми хочемо (і це робимо в цьому випадку UTF-8), ми можемо просто залишити це неоднозначно, і програма все одно працює.
Кінець кожного з 3…
розділів є 525
, який скидає вихідний формат, і ми повернемося до 551
наступного розділу.
a
s - чи ні, залежно від кількості букви, які знадобляться, бо 20 символів - це справді велика кара (хоча коли все інше набирається байтами, це не зовсім чітко визначено ...)!