Інтерпретувати TwoMega


9

У цьому виклику ви напишете інтерпретатора на 2 Ω (транскрипцію як TwoMega ), мовою, заснованої вільно на головному мовленні з нескінченномірним простором зберігання.

Мова

2 Ом містить три стани:

  • Стрічка , яка представляє собою нескінченний список бітів, все не започатковано в 0. Це має крайній лівий елемент, але не крайній правий елемент.

  • Покажчик пам'яті , яка представляє собою невід'ємне ціле число , яке є індексом елемента в стрічці. Більш високий вказівник пам'яті відноситься до комірки стрічки далі праворуч; покажчик пам'яті 0 відноситься до лівого лівого елемента. Покажчик пам'яті ініціалізується на 0.

  • Гіперкуба , який є концептуально - мірним «вікном» осередків, кожен з яких містить біт , ініціалізувати в 0. ширина гіперкуба пов'язана в кожному вимірі тільки 2 клітин, але нескінченність розмірів означає число клітини незлічувані .

Індекс в гіперкуб нескінченного список біт, відноситься до клітки , в гиперкуба (таким же чином , що кінцевий список біт може бути використаний для позначення гиперкуба кінцевої розмірності). Оскільки стрічка - це нескінченний перелік бітів, вся стрічка завжди посилається на елемент гіперкуби; цей елемент називається референтом .

2 Ω надає значення 7 різних символів:

  • < зменшує вказівник пам'яті на 1. Зменшення його нижче 0 - це невизначена поведінка, тому вам не потрібно з цим обробляти.
  • > збільшує покажчик пам'яті на 1.
  • ! перевертає шматочок у референта.
  • . виводить біт на референта.
  • ^замінює біт у комірці, на який вказує вказівник пам'яті на стрічці, оберненим бітом у референта.
  • [x]запускає код до xтих пір, поки біт у референта дорівнює 1.

Змагання

Ваше завдання - написати програму, яка приймає рядок як вхідний і виконує цей вхід як 2 Ω програма.

Це є , тому найкоротший вірний відповідь (вимірюється в байтах) виграє.

Примітки

  • Можна припустити, що програма буде складатися виключно з персонажів, <>!.^[]які []будуть належним чином вкладені.
  • Ваш перекладач повинен бути обмежений лише наявною пам'яттю в системі. Він повинен мати можливість запускати зразкові програми за розумну кількість часу.

Зразкові програми

Друк 1:

!.

Друк 010:

.!.!.

Друкувати 0 назавжди:

![!.!]

Друкуйте 0 назавжди або 1 назавжди, якщо !це попередньо:

[.]![!.!]

2
Невелика примітка: кількість комірок для зберігання насправді не рахується, оскільки кількість 1s на стрічці завжди обмежена. Насправді між природними числами та станами стрічки існує досить проста біекція (інтерпретуйте вміст стрічки як бінарне число назад), що показує, що Гіперкуба - це в основному нескінченний 1D масив, доступ до якого здійснюється шляхом перегортання бітів у цілочисельне значення вказівника. , замість in / decrementing, як у brainfuck.
Лінн

Крім того, повторно: ваше запрошення до написання catпрограми: не здається, що існує інструкція щодо введення інформації.
Лінн

2
Я думаю, що слід мати приклади програм, що використовують більше наборів інструкцій. Дві прості: .- друкує один нуль і тоді існує; !^!.- друкує один, потім виходить. Хоча більше було б добре. На даний момент ви повинні зрозуміти подання, щоб перевірити їх (і, отже, підтримати їх!)
Джонатан Аллан

@Lynn Введення буде зроблено, маючи або 1, або 0 на комірці [0,0,0,0,0,0,0...](тобто наявність a !на початку програми).
Esolanging Fruit

Тоді ви можете зробити, [.]![!.!]щоб назавжди надрукувати значення цієї клітинки
Лев

Відповіді:


2

Python 2 , 167 байт

t=h=I=0
m=1
E=''
for c in input():i='[<>!.^]'.find(c);E+=' '*I+'while+2**t&h: m/=2 m*=2 h^=2**t print+(2**t&h>0) t=t&~m|m*(2**t&h<1) #'.split()[i]+'\n';I-=~-i/5
exec E

Спробуйте в Інтернеті!

t - стрічка. t = 6 означає, що стрічка є [0 1 1 0 0 0…]

m дорівнює 2 потужності вказівника пам'яті. Тож m = 8 означає, що ми вказуємо на біт стрічки 3.

h - гіперкуб. h = 80 (біт 4 і 6 встановлено) означає, що біти при [0 0 1 0…] і [0 1 1 0…] встановлені.

Щоб прочитати біт у референта, ми перевіряємо 2 т і год . Щоб перевернути його, виконуємо h ^ = 2 t .

Ми переводимо інструкції в код Python і виконуємо результат. Я зберігаю рівень відступу циклів while.


Або ваша програма, або другий тестовий випадок невірний
wastl

@wastl Другий тестовий випадок помилився. ;)
DLosc


2

JavaScript (Node.js) , 148 байт

x=>eval(x.replace(e=/./g,c=>({'<':'u/=2','>':'u*=2','!':'e[v]^=1','.':'alert(+!!e[v])','^':'v=(v|u)^u*e[v]','[':'while(e[v]){'}[c]||'}')+';',v=u=1))

Спробуйте в Інтернеті!

Це завершення

BoolFuck TwoMega
< >^>^>[!]^<<<<[!]^>>[!]!^>[!]!^>[!]!^<<<<(>^>^>1<<<<1>>0>0>0<<<<)
> ^<^<[!]^>>>>[!]^<<[!]!^<[!]!^<[!]!^>>>(^<^<1>>>>1<<0<0<0>>>)

Потрібно init, як рухається в декількох місцях, і init поточний і правий один біт адреси як 1 ( >>>>>>>>^>^<)

Спробуйте в Інтернеті!

Місце nв BoolFuck написано як (0, 0, ..., 0(n*0), [1], 1, 0, 0, ...).

Бо >це робить n=>n+1

     0 0 0 0 0[1]1 0 0 0 0
^    0 0 0 0 0[x]1 0 0 0 0
<    0 0 0 0[0]x 1 0 0 0 0
^    0 0 0 0[y]x 1 0 0 0 0, yx != 01
<    0 0 0[0]y x 1 0 0 0 0
[!]^ 0 0 0[1]y x 1 0 0 0 0, (0yx10) = 0
>>>> 0 0 0 1 y x 1[0]0 0 0
[!]^ 0 0 0 1 y x 1[1]0 0 0, (1yx10) = 0
<<   0 0 0 1 y[x]1 1 0 0 0
[!]! 0 0 0 1 y[x]1 1 0 0 0, (1yx11) = 1
^    0 0 0 1 y[0]1 1 0 0 0
<    0 0 0 1[y]0 1 1 0 0 0
[!]! 0 0 0 1[y]0 1 1 0 0 0, (1y011) = 1
^    0 0 0 1[0]0 1 1 0 0 0
<    0 0 0[1]0 0 1 1 0 0 0
[!]! 0 0 0[1]0 0 1 1 0 0 0, (10011) = 1
^    0 0 0[0]0 0 1 1 0 0 0
>>>  0 0 0 0 0 0[1]1 0 0 0

Те саме, як <працює


Ви впевнені, що цей переклад дійсний? !>.друкує 1в boolfuck, але перекладається на те, !>^.що друкує 1 у TwoMega ( >не впливає на стрічку; ^не впливає на стрічку, оскільки референт - 1)
Esolanging Fruit

@EsolangingFruit +>;do [1]00... 1[0]0...(вихід 0), !>^.do (0,0,...)=1, ptr=([0],0,...) (0,0,...)=1, ptr=(0,[0],...) (0,0,...)=1, ptr=(0,[1],...)(вихід 0), що не так?
l4м2

@EsolangingFruit for !>., лише >допустима команда в boolfuck ...
лише ASCII

1
@ l4m2 У TwoMega !інвертує референт, а не комірку стрічки.
Esolanging Fruit

@EsolangingFruit, то що тут не так?
l4м2

1

Brain-Flak Classic , 816 байт

<>(((<(())>)))<>{(([][][])(((({}){}[])({}))({})[]([][](({})(({}())(({}){}{}({}(<()>))<{<>({}<>)}{}>))))))(([]{()(<{}>)}{}){<((<{}>))<>(()(){[](<{}>)}{}<{({}[]<({}<>)<>>)}{}{}>)<>({()<({}<>)<>>}<<>{<>(({}){}<>({}<>)[])<>}{}<>({()<({}[]<<>({}<>)>)>}{})<>(({})<<>{({}[]<({}<>)<>>)}({}<>)<>{({}<>)<>}>)<>>)<>({}<>)<>>}{}([]{()(<{}>)}{}){{}<>({})(<>)}{}([]{()(<{}>)}{}){(<{}<>({}<{((<({}[])>))}{}{((<(())>))}{}>)<>>)}{}([]{()(<{}>)}{}){(<{}<>({}<({}())>)<>>)}{}([]{()(<{}>)}{}){(<{}<>[({})]<>>)}{}([]{()(<{}>)}{})<{((<{}>))<>{}({}<{<>(({}){}<>({}<>)[])<>}{}<>({()<({}[]<<>({}<>)>)>}{})<>(((){[](<{}>)}{})<<>{({}[]<({}<>)<>>)}{}(<>)<>{({}<>)<>}>)<>>)<>({}<>)<>}{}(<>)<>{({}<>)<>}{}>()){((({}[]<>){(<{}({}<>)>)}{}())<{({}<({}<>)<>((((((([][][]){}){}){}()){}){}({})())[][])>{[](<{}>)}{}{()(<{}>)}{})}{}({}<>)>[]){{}(<>)}}{}}

Спробуйте в Інтернеті!

Цей код був написаний просто для того, щоб мені було де написати доказ Тюрінгової повноти.

Доказ Тюрінга-повноти

Ми показуємо скорочення від Boolfuck до TwoMega:

Boolfuck   TwoMega
>          >>
<          <<
.          !^!.!^!
[          !^![!^!
]          !^!]!^!
+          !^[!]^[>!^<[!]!^>[!]!^<]

Цей переклад зберігає стан Boolfuck у парних клітинках стрічки в TwoMega. Усі перекладені команди зберігатимуть наступних інваріантів:

  • Покажчик пам’яті знаходиться на комірці з парним числом.
  • Усі непарні номери клітинок стрічки дорівнюють нулю.
  • Для будь-якої можливої ​​стрічки з усіма одиницями з непарними нумерами відповідне значення на гіперкубі дорівнює нулю.

Фрагмент !^!буде зберігати [0]0постійний і змінюватись між ( 0[0]і [1]1(якщо увага обмежена лінією на гіперкубі, доступною без переміщення покажчика пам'яті). Як такий, він використовується для тимчасового введення поточного значення стрічки в референт для команд Boolfuck, які турбуються про нього.

Якби TwoMega дали команду введення ,з очікуваною семантикою, команда Boolfuck ,перекладеться на >^<,!^>[!]!^<. Оскільки ,не потрібно доводити, що Boolfuck є повним Тьюрінгом, відсутність команди введення не впливає на цей доказ.


В основному він зберігає інформацію в положенні в гіперкубі, а не в самому кубі?
l4m2

@ l4m2 Моє скорочення від BoolFuck не зберігає жодних даних у самому кубі. Будь-які 1, які я роблю на гіперкубі, є лише там, щоб встановити клітинки стрічки на 0.
Nitrodon,

0

Python 3 , 297 284 274 байт

-10 байт завдяки овам і Джонатану Аллану

C=input()
h={}
t=set()
def f(C,p):
 c=C[0];r=hash(frozenset(t));v=h.get(r,0)
 p={"<":p-1,">":p+1}.get(c,p)
 if'"'>c:h[r]=not v
 if"."==c:print(int(v))
 if"]"<c:t.discard(p)if v else t.add(p)
 if"["==c:
  while f(C[1:],p):1
 else:return c=="]"and v or C and f(C[1:],p)
f(C,0)

Спробуйте в Інтернеті!


t.discard(p)->t-={p}
shooqie

@shooqie Це не працює, якщо tнемає global.
fergusq

@fergusq Хоча я впевнений, що це працює, якщо ти ff(C,p,t=set())
оголосиш

0

Піп , 75 71 байт

lPB0aR:^"!><[].^_""!:_
--viPU0
++v
W_{
}
O_
i@v:!_LFBilPB0
l@FBi"^n;Vau

Спробуйте в Інтернеті!

Переводить 2 Ω код в еквівалентний код Pip і оцінює його.

Ми використовуємо iдля представлення стрічки, vдля вказівника стрічки * та lдля гіперкуба. Перші два стають попередньо до корисних цінностей; lпочинається як [], до чого ми натискаємо 0( lPU0), щоб уникнути проблем з індексом-порожнім списком.

* Власне, це бітове заперечення вказівника стрічки, оскільки ми зберігаємо стрічку назад для легшого перетворення в десятковий.

Решта коду:

aR:...;     Do a bunch of replacements in a, translating it into Pip code
       Va   Evaluate a
         u  Suppress output of the final expression that was evaluated

Таблиця перекладів:

!  !:_
>  --viPU0
<  ++v
[  W_{
]  }
.  O_
^  i@v:!_LFBilPB0
_  l@FBi

l@FBiє референтом: елемент гіперкуба lв індексі (перетворити iз двійкового). Він з’являється часто, тому ми його називаємо _і замінюємо _реальним кодом наприкінці.

  • !:_ логічно заперечує референт на місці.

  • --viPU0декременти v(переміщення покажчика стрічки вправо); Потім він натискає інший 0на лівий бік i, щоб переконатися, що вказівник стрічки залишається в межах.

  • ++vз кроком v(не потрібно перевіряти межі, за ОП).

  • W_{виконує цикл, поки референт є truthy (тобто ненульовий, тобто 1).

  • } закриває петлю.

  • O_ виводить референта без нового рядка.

Нарешті, для ^:

i@v:            Set the current tape cell to
    !_          The logical negation of the referent
                Now, make sure the list representing the hypercube is long enough:
      LFBi      Loop frombinary(i) times:
          lPB0  Push another 0 to the end of l
                This ensures that FBi will always be a valid index into l
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.