Дивна випадковість, що цей світ має лише один часовий вимір, але він не повинен бути таким. Легко уявити світи з двома і більше часовими вимірами, і в цих світах ви могли б створити комп'ютери та запустити на них програмне забезпечення, як у цьому.
Система
Ось система для запуску програм Brainf * ck у двох часових вимірах:
Два часові розміри - x і y. Кожна програма Brainf * ck складається з x напівпрограми, і будь-яка напівпрограма, наприклад, програма може бути
x: +>+
y: [-]
Дві напівпрограми мають власну вказівку програми, але вони поділяють один покажчик стрічки (тобто обидва вони працюють на одній клітинці стрічки).
Час двовимірний, тому складається з сітки моментів:
Рухаючись по розміру x, половина програми x виконує один крок часу. Рухаючись по розміру y, півпрограма виконує один крок часу.
Наприклад, скажімо, стрічка починається як [0] 0 0
( []
являє собою покажчик стрічки), а програми x / y є +
і ->-
. Виконання цієї програми виглядатиме так:
x y tape x-action y-action
0 0 [ 0] 0 0 + at 0 - at 0
1 0 [ 1] 0 0 (done) - at 0
0 1 [-1] 0 0 + at 0 move >
1 1 [ 0] 0 0 (done) move >
Зауважте, що, коли час рухається у напрямку у, половина програми x продовжує робити те саме, що повторюється, оскільки його час не прогресує.
Стрічка в кожен момент включає сукупний ефект усіх дій, які в неї подаються (кожна дія рахується один раз). Так, наприклад, стрічка в момент часу (2, 1) містить сукупний ефект:
- x-дія від (0, 0)
- x-дія від (1, 0)
- x-дія від (0, 1)
- x-дія від (1, 1)
- y-дія від (0, 0)
- y-дія з (1, 0)
- y-дія з (2, 0)
Накопичувальні засоби:
- Всі прирости і зменшення до клітинки сумуються разом.
- Усі ліві (-1) та праві (+1) рухи до вказівника стрічки складаються разом.
Покажчики інструкцій не накопичуються. Кожна напівпрограма отримує свій вказівник з попереднього моменту у своєму вимірі. Тобто, покажчики програми x просуваються лише у розмірності x, а покажчики програми y просуваються лише у вимірі y. Так, наприклад, у програмі ( []
, +
), що починається з [0] 0 0
, виконання буде
x y tape x-action y-action x-prog-ptr y-prog-ptr
0 0 0 0 0 + at 0 0 0
1 0 0 0 0 + at 0 2 (from jump) 0
0 1 1 0 0 0 1
1 1 2 0 0 1 (from NO jump) 1
Ще кілька моментів із вищезгаданого ( +
, ->-
) моделювання:
x y tape x-action y-action x-prog-ptr y-prog-ptr
0 0 [ 0] 0 0 + at 0 - at 0 0 0
1 0 [ 1] 0 0 - at 0 1 0
2 0 [ 1] 0 0 - at 0 1 0
0 1 [-1] 0 0 + at 0 > 0 1
1 1 [ 0] 0 0 > 1 1
2 1 [-1] 0 0 > 1 1
0 2 -1 [ 0] 0 + at 1 - at 1 0 2
1 2 0 1 [ 0] - at 2 1 2
2 2 [-1] 1 0 - at 0 1 2
Дозволені наступні оператори Brainf * ck (вони мають своє стандартне значення):
+
,-
: приріст, декремент;[
,]
: цикл до нуля (обробка a[
або]
займає один крок часу, як у стандартному Brainf * ck);<
,>
: рухайтесь ліворуч / праворуч на стрічці.
Складний приклад
Для програми ( >
, +
), що починається з [0] 0 0
:
x y tape x-action y-action x-prog-ptr y-prog-ptr
0 0 [ 0] 0 0 > + at 0 0 0
1 0 0 [ 0] 0 + at 1 1 0
0 1 [ 1] 0 0 > 0 1
1 1 1 1 [ 0] 1 1
Для ( +
, -
), починаючи з [0] 0 0
:
x y tape x-action y-action x-prog-ptr y-prog-ptr
0 0 [ 0] 0 0 + at 0 - at 0 0 0
1 0 [ 1] 0 0 - at 0 1 0
0 1 [-1] 0 0 + at 0 0 1
1 1 [ 0] 0 0 1 1
Зауважте, що стрічка закінчується так, [0] 0 0
як кожна, +
і -
відбувається двічі, підсумовуючи 0.
Для програми ( >+
, [-]
), що починається з [0] 0 0
:
x y tape x-action y-action x-prog-ptr y-prog-ptr
0 0 [ 0] 0 0 > 0 0
1 0 0 [ 0] 0 + at 1 1 0
2 0 0 [ 1] 0 2 0
0 1 [ 0] 0 0 > 0 3
1 1 0 0 [ 0] + at 2 1 3
2 1 0 1 [ 1] - at 2 2 1
0 2 [ 0] 0 0 > 0 3
1 2 [ 0] 0 0 + at 0 1 3
2 2 [ 1] 1 0 2 2
Діаграма зі стрілками
На схемі нижче показано, як обчислити дії та стрічку:
Головоломка
Напишіть програму 2D Brainf * ck (з х-програмою та половиною програми) для запуску на триклітинній стрічці, яка задовольняє обом наступним умовам:
- Якщо стрічка починається так
[0] 0 0
, як за часом (5, 5), вона має0
нульову комірку. - Якщо стрічка починається так
[1] 0 0
, як за часом (5, 5), вона має0
нульову комірку.
Виграє найкоротша програма, що відповідає вимогам.
+
, >
), щоб побачити, чи отримаю я такий самий результат, як і ви.
(1,1)
через (1,0)
або (0,1)
, але це одна програма починається з >
однієї і починається +
, то, безумовно, їх відносний порядок має значення?
+
та>
? Якщо це1 1 [0]
(досить божевільно, але, як видається, пропонує специфікація), як поєднуються вказівники інструкцій? Якщо два потоки є+
і[]
, то на1 2
стрічці даних буде[3]
, але чи є другий вказівник інструкції всередині циклу ([]+
шлях), або зовні ([+]
шлях), або навіть незаконний (+[]
)?