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наступного розділу.
as - чи ні, залежно від кількості букви, які знадобляться, бо 20 символів - це справді велика кара (хоча коли все інше набирається байтами, це не зовсім чітко визначено ...)!