BlockScript - 535
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
BlockScript - це тривіальна мова, основана на стеці спагетті, яку я створив спеціально для цього завдання. Базовим перекладачем є blockcript.c .
Зразок програми (друкує перші 15 чисел Фібоначчі):
{[B?B10/A!B10%d&:0}
{[B0<?'-.0B-A!:{B?Bh!{[B?B[A]A!B[B]'0+.:}!:'0.}!10.}
{[B?Dd!DC+B1-CecA!:}
0 1 15d!
;
Інтерпретатор зчитує як вихідний код, так і програмний вхід із стандартного вводу в такому порядку. Це означає, що для запуску інтерпретатора в інтерпретаторі просто перекопіюйте та вставте:
# Level 1
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
# Level 2
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
# Level 3
{[B?B10/A!B10%d&:0}
{[B0<?'-.0B-A!:{B?Bh!{[B?B[A]A!B[B]'0+.:}!:'0.}!10.}
{[B?Dd!DC+B1-CecA!:}
0 1 15d!
;
Як і фільм « Початок» , ви майже не можете пройти глибше трьох рівнів. Це не питання часу, а простору. BlockScript рясно просочує пам'ять, і це пов'язано з тим, як створена сама мова.
Довідкова мова:
Знайдіть перекладача тут
У BlockScript "стек" - це не масив, який перезаписується наступними операціями, до яких можна звикнути. Він фактично реалізований як незмінний пов'язаний список, а стек зберігається протягом тривалості програми. Також жоден оператор (крім @
) не видаляє значення зі стека. Однак модифікації стека впливають лише на блок, в якому вони відбуваються.
Вибір значення
a
наскрізь z
Дістаньте 0-25-й елемент із стека та натисніть на стек. a
посилається на голову або останній висунутий предмет стопки.
A
наскрізь Z
Витягніть 0-25-й елемент поточного кадру та натисніть на стек.
[
Відкрийте "кадр" для вибору елементів із посилання на стек (див. Нижче) на голові стека. [
не вимагає відповідності ]
, але кадри мають лексичний діапазон. У BlockScript "область" визначається дужками ( {
... }
), які утворюють блоки. Таким чином, відкриття кадру всередині блоку не матиме впливу на код поза блоком.
]
Закрийте поточний кадр, повертаючись до попереднього кадру (якщо такий є).
Блоки
{
... }
Створіть "блок" і натисніть на стек. Всередині блоку стек починатиметься з того, що був до блоку, за винятком того, що стек абонента буде висунутий зверху. Стеки стійкі та незмінні в BlockScript, тому блоки є закриттями. Ідіома {[
означає відкрити блок, а потім відкрити кадр для початку вибору аргументів (за допомогою A
наскрізного Z
). Повернене значення блоку - це голова стека, коли }
буде досягнуто.
Приклад:
'3 '2 '1 {[ b. d. f. B. C. D. A! } 'D 'C 'B d!;
Це відбитки 123BCD123DCB123BCD123DCB…
. Малі літери відносяться до значень стека, а великі літери - до аргументів (тому що кадр встановлений у стеку абонента). A!
приймає голову абонента (що гарантовано називається блоком, що викликається) і називає його. Якщо вам цікаво, чому він реверсується BCD
кожен раз, це тому, що B. C. D.
підштовхує ці аргументи у зворотному порядку прямо перед тим, як блокує дзвінок.
!
Викличте блок. Натисніть повернення на стек.
Посилання на стеки
&
Створіть посилання на стек та натисніть на стек. Подумайте про це як про «супер-мінуси», оскільки воно ефективно бере кожен предмет у стеку і утворює з нього «кортеж». Ідіоми &[
означає , що все a
, b
, c
згадані дотепер часу можуть бути доступні з A
, B
, C
(для решти блоку або поки ]
не зустрінеться).
Почасти тому, що &
фіксує більше значень, ніж зазвичай потрібно, BlockScript просочує пам'ять за конструкцією.
@
Переключіться на стек, на який вказує посилання стека a
. Цей оператор досить дивний, але самоінтерпретатор BlockScript використовує його кілька разів, щоб уникнути необхідності двічі висувати одні й ті ж аргументи. Ефекти @
(або будь-якої операції стека з цього питання) обмежуються блоком, в який він викликається. Також на кадр це не впливає @
, тому кадр можна використовувати для отримання значень, необхідних вам після переключення стеків.
Умовне вираження
?
<на правду> :
<на помилково>
Умовне вираз, як і потрійний оператор у C. Тобто, якщо a
"true" (тобто не дорівнює цілому нулю), тоді зробіть <on true> , інакше зробіть <on false> .
I / O
Примітка. Введення та виведення здійснюються в UTF-8. "Символ" - це ціле число, що відповідає індексу Unicode.
,
Отримайте наступний символ введення та натисніть його на стек. Якщо кінець вводу досягнуто, натисніть -1 замість цього.
.
Виведіть символ на голову стека.
Цілі літери / символи
Примітка. Цілі символи та символи - це одне і те ж саме в BlockScript.
Арифметика
Ці оператори працюють лише на цілі значення.
+
Обчислити b
+ a
(підштовхуючи результат, але не відкидаючи жодного значення).
-
Обчислити b
- a
.
*
Обчислити b
* a
.
/
Обчислити b
/ a
(ціле ділення; округлює до негативної нескінченності).
%
Обчисліть b
% a
(цілий модуль; округлює до негативної нескінченності).
Реляційні оператори
Ці оператори працюють лише на цілі значення.
<
Якщо b
менше a
, натисніть 1, інакше натисніть 0.
>
=
Різне
#
Прокоментувати до кінця рядка
- Програма повинна закінчуватися
;
- Усі інші символи ігноруються.
/usr/bin/cat
) що з Тюрінг-повнотою?