Непогано для досить багатослівного тарінгу Тюрінга ...
N
Count i while _%128-9 {
Count x while _/128%2 {
Write 40
_+128
}
Write _%128
_+128-_%128+N
}
Count j while _/256-j {
Write 41
}
(Так, усе, що пробіл є обов'язковим.)
Примітка: через вхідні обмеження Acc !! , неможливо прочитати довільну рядок символів без деякого закінчення розмежувача. Таким чином, ця програма очікує введення (на stdin) у вигляді рядка з подальшим символом вкладки.
Acc !!?
Я створив мову, яка видається лише непридатною . Єдиний тип даних - цілі числа, єдиною конструкцією потоку управління є Count x while y
цикл, і єдиний спосіб зберігання даних - це один акумулятор _
. Введення та виведення здійснюються по одному символу, використовуючи спеціальне значення N
та Write
заяву. Незважаючи на ці обмеження, я цілком впевнений, що Acc !! є Тьюрінгом.
Пояснення
Основна стратегія в Acc !! Програмування полягає у використанні мод %
і цілого поділу /
для концептуального розподілу акумулятора, що дозволяє йому зберігати відразу декілька значень. У цій програмі ми використовуємо три такі розділи: сім біт нижчого порядку ( _%128
) зберігає ASCII-код з введення; наступний біт ( _/128%2
) зберігає значення прапора; а решта бітів ( _/256
) підраховують кількість закритих паролів, які нам знадобляться.
Введення в Acc !! походить від спеціального значення N
, яке читає один символ і оцінює його ASCII-код. Будь-яке твердження, що складається виключно з виразу, присвоює результат цього виразу акумулятору. Отже, ми почнемо зі зберігання коду першого символу в акумуляторі.
_%128
буде зберігати останнього прочитаного символу. Отже, перший цикл працює у той час, коли він не _%128-9
є нульовим, тобто поки поточний символ не є вкладкою.
Всередині циклу ми хочемо надрукувати, (
якщо ми не переглянемо першу ітерацію. З моменту Acc !! не має оператора if, ми повинні використовувати петлі для умовних умов. Ми використовуємо 128 біт акумулятора _/128%2
, як значення прапора. На першому проході єдине, що в акумуляторі - це значення ASCII <128, тому прапор дорівнює 0 і цикл пропускається. При кожному наступному пропуску ми переконаємось, що прапор дорівнює 1.
Всередині Count x
циклу (коли прапор дорівнює 1) ми пишемо відкритий paren (ASCII 40
) і додаємо 128 до акумулятора, тим самим встановлюючи прапор 0 і виходячи з циклу. Це також відбувається з збільшенням значення _/256
, яке ми будемо використовувати як наш підрахунок близько закритих парен для виведення.
Незалежно від значення прапора, ми пишемо останню графіку введення, що просто _%128
.
Наступне завдання ( _+128-_%128+N
) виконує дві речі. По-перше, додавши 128, він встановлює прапор в наступний раз через цикл. По-друге, він нульово виділяє _%128
слот, читає інший символ і зберігає його там. Потім петлю.
Коли Count i
цикл виходить, ми просто прочитали символ вкладки, і значення акумулятора розбивається так:
_%128
: 9
(символ вкладки)
_/128%2
: 1
(прапор)
_/256
: кількість прочитаних символів, мінус 1
(Мінус 1 пояснюється тим, що ми додаємо 128 до акумулятора лише один раз під час першого проходу через основну петлю.) Все, що нам зараз потрібно, - це близькі парони. Count j while _/256-j
циклічних _/256
разів, 41
щоразу записуючи близький батько (ASCII ). Вуаля!