Phiên dịch TwoMega


9

Trong thử thách này, bạn sẽ viết một thông dịch viên cho 2 Ω (phiên âm như TwoMega ), một ngôn ngữ dựa trên lỏng lẻo Brainfuck với một không gian lưu trữ vô hạn chiều.

Ngôn ngữ

2 Ω chứa ba mẩu của nhà nước:

  • Các băng , mà là một danh sách vô hạn các bit, tất cả khởi tạo là 0. Nó có một yếu tố tận cùng bên trái, nhưng không có yếu tố ngoài cùng bên phải.

  • Các Memory Pointer , mà là một số nguyên dương đó là một chỉ số của một phần tử trong băng. Một con trỏ bộ nhớ cao hơn đề cập đến một ô băng ở bên phải; một con trỏ bộ nhớ bằng 0 đề cập đến phần tử ngoài cùng bên trái. Con trỏ bộ nhớ được khởi tạo thành 0.

  • Các Hypercube , mà là một khái niệm "hộp" chiều của các tế bào, mỗi trong số đó có chứa một chút khởi tạo là 0. Chiều rộng của Hypercube được ràng buộc trong mọi khía cạnh để chỉ có 2 tế bào, nhưng tính vô hạn của kích thước có nghĩa là số tế bào là không thể đếm được .

Một chỉ mục vào hypercube là một danh sách các bit liên quan đến một ô trong hypercube (giống như cách mà một danh sách các bit hữu hạn có thể được sử dụng để chỉ một hypercube có kích thước hữu hạn). Bởi vì băng là một danh sách các bit vô hạn, toàn bộ băng luôn đề cập đến một phần tử của Hypercube; yếu tố này được gọi là người giới thiệu .

2 Ω cho ý nghĩa cho 7 nhân vật khác nhau:

  • < giảm con trỏ bộ nhớ bằng 1. Giảm xuống dưới 0 là hành vi không xác định, do đó bạn không cần phải xử lý nó.
  • > tăng con trỏ bộ nhớ lên 1.
  • ! lật bit tại người giới thiệu.
  • . đầu ra bit tại tham chiếu.
  • ^thay thế bit tại ô được trỏ bởi con trỏ bộ nhớ trên băng bằng nghịch đảo của bit tại tham chiếu.
  • [x]chạy mã xmiễn là bit tại tham chiếu là 1.

Các thách thức

Nhiệm vụ của bạn là viết một chương trình lấy một chuỗi làm đầu vào và thực hiện đầu vào đó là chương trình 2 Ω .

Đây là , vì vậy câu trả lời hợp lệ ngắn nhất (tính bằng byte) sẽ thắng.

Ghi chú

  • Bạn có thể giả định rằng chương trình sẽ chỉ bao gồm các ký tự <>!.^[][]sẽ được lồng đúng cách.
  • Thông dịch viên của bạn chỉ nên bị giới hạn bởi bộ nhớ khả dụng trên hệ thống. Nó sẽ có thể chạy các chương trình mẫu trong một khoảng thời gian hợp lý.

Chương trình mẫu

In 1:

!.

In 010:

.!.!.

In 0 mãi mãi:

![!.!]

In 0 mãi mãi hoặc 1 mãi mãi nếu !được trả trước:

[.]![!.!]

2
Một lưu ý nhỏ: số lượng tế bào lưu trữ thực sự không thể đếm được, vì số lượng 1s trên băng luôn luôn là hữu hạn. Trên thực tế, có một sự lựa chọn khá đơn giản giữa các số tự nhiên và trạng thái băng (diễn giải nội dung băng là số nhị phân ngược), cho thấy Hypercube về cơ bản là một mảng 1D vô hạn, được truy cập bằng cách lật các bit trong một giá trị con trỏ nguyên , thay vì trong / giảm như trong brainfuck.
Lynn

Ngoài ra, re: lời mời của bạn để viết một catchương trình: dường như không có một hướng dẫn nào để nhận đầu vào.
Lynn

2
Tôi nghĩ nên có các chương trình mẫu sử dụng nhiều tập lệnh hơn. Hai chương trình đơn giản: .- in một số 0 duy nhất và sau đó tồn tại; !^!.- in một cái duy nhất sau đó thoát ra. Nhiều hơn sẽ tốt mặc dù. Tại thời điểm này, người ta phải hiểu các bài nộp để xác minh chúng (và do đó nâng cao chúng!)
Jonathan Allan

@Lynn Đầu vào sẽ được cung cấp bằng cách có 1 hoặc 0 trên ô [0,0,0,0,0,0,0...](tức là sự hiện diện của a !khi bắt đầu chương trình).
Esolanging Fruit

Sau đó, bạn có thể làm [.]![!.!]để in giá trị của ô đó mãi mãi
Leo

Câu trả lời:


2

Python 2 , 167 byte

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

Hãy thử trực tuyến!

t là băng. t = 6 có nghĩa là băng là [0 1 1 0 0 0]

m là 2 với sức mạnh của con trỏ bộ nhớ. Vậy m = 8 có nghĩa là chúng ta đang chỉ vào băng bit 3.

h là siêu âm. h = 80 (bit 4 và 6 set) có nghĩa là các bit tại [0 0 1 0]] và [0 1 1 0]] được đặt.

Để đọc bit tại người giới thiệu, chúng tôi kiểm tra 2 t & h . Để lật nó, chúng tôi thực hiện h ^ = 2 t .

Chúng tôi dịch các hướng dẫn sang mã Python và thực hiện kết quả. Tôi lưu trữ mức độ thụt của các vòng lặp while.


Chương trình của bạn hoặc trường hợp thử nghiệm thứ hai đều sai
lãng phí

@wastl Trường hợp thử nghiệm thứ hai đã sai. ;)
DLosc


2

JavaScript (Node.js) , 148 byte

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))

Hãy thử trực tuyến!

Nó đã hoàn tất

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

Cần init như di chuyển đúng vài vị trí và khởi tạo một bit hiện tại và bên phải của địa chỉ là 1 ( >>>>>>>>^>^<)

Hãy thử trực tuyến!

Đặt ntrong BoolFuck được viết là (0, 0, ..., 0(n*0), [1], 1, 0, 0, ...).

>, nó làm 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

Tương tự như cách <làm việc


Bạn có chắc bản dịch này là hợp lệ? !>.in 1bằng boolfuck nhưng dịch sang !>^.in 1 trong TwoMega ( >không ảnh hưởng đến băng; ^không ảnh hưởng đến băng vì người giới thiệu là 1)
Esolanging Fruit

@EsolangingFnut +>;làm [1]00... 1[0]0...(đầu ra 0), !>^.làm (0,0,...)=1, ptr=([0],0,...) (0,0,...)=1, ptr=(0,[0],...) (0,0,...)=1, ptr=(0,[1],...)(đầu ra 0), có gì sai?
l4m2

@EsolangingFnut cho !>., chỉ >là một lệnh hợp lệ trong boolfuck ...
ASCII-chỉ

1
@ l4m2 Trong TwoMega, !đảo ngược người giới thiệu, không phải ô băng.
Esolanging Fruit

@EsolangingFnut vậy có gì sai ở đây?
l4m2

1

Brain-Flak Classic , 816 byte

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

Hãy thử trực tuyến!

Mã này được viết chỉ để tôi có một nơi để viết bằng chứng về tính đầy đủ của Turing.

Bằng chứng về Turing-đầy đủ

Chúng tôi hiển thị mức giảm từ Boolfuck xuống TwoMega:

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

Bản dịch này lưu trữ trạng thái Boolfuck trong các ô băng được đánh số chẵn trong TwoMega. Tất cả các lệnh được dịch sẽ bảo tồn các bất biến sau:

  • Con trỏ bộ nhớ nằm ở một ô số chẵn.
  • Tất cả các ô băng số lẻ đều bằng không.
  • Đối với bất kỳ băng có thể có tất cả các ô số lẻ bằng 0, giá trị tương ứng trên hypercube là 0.

Đoạn mã !^!sẽ giữ [0]0liên tục và trao đổi giữa 0[0][1]1(trong đó sự chú ý được giới hạn ở dòng trên hypercube có thể tiếp cận mà không di chuyển con trỏ bộ nhớ). Như vậy, nó được sử dụng để tạm thời đặt giá trị băng hiện tại vào tham chiếu cho các lệnh Boolfuck quan tâm đến nó.

Nếu TwoMega được cung cấp một lệnh đầu vào ,với ngữ nghĩa dự kiến, lệnh Boolfuck ,sẽ dịch sang >^<,!^>[!]!^<. Vì ,không cần thiết phải chứng minh rằng Boolfuck là Turing-Complete, việc thiếu lệnh đầu vào không ảnh hưởng đến bằng chứng này.


Nó chủ yếu lưu trữ thông tin ở vị trí trong hypercube chứ không phải là khối lập phương?
l4m2

@ l4m2 Giảm của tôi từ BoolFuck không lưu trữ bất kỳ dữ liệu nào trong khối. Bất kỳ 1 giây nào tôi thực hiện trên hypercube chỉ ở đó để đặt các ô băng thành 0.
Nitrodon

0

Python 3 , 297 284 274 byte

-10 byte nhờ vào ovs và Jonathan Allan

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)

Hãy thử trực tuyến!


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

@shooqie Điều đó không hoạt động trừ khi tglobal.
fergusq

@fergusq Mặc dù tôi khá chắc chắn rằng nó hoạt động nếu bạn tuyên bố ff(C,p,t=set())
shooqie

0

Pip , 75 71 byte

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

Hãy thử trực tuyến!

Dịch 2 Ω mã vào mã Pip tương đương và đánh giá lại nó.

Chúng tôi sử dụng iđể đại diện cho băng, vcho con trỏ băng * và lcho hypercube. Hai cái đầu tiên được ưu tiên hóa thành các giá trị hữu ích; lbắt đầu như [], mà chúng ta đẩy một 0( lPU0) để tránh các vấn đề về lập chỉ mục-danh sách trống.

* Trên thực tế, đó là sự phủ định theo chiều bit của con trỏ băng, bởi vì chúng tôi đang lưu trữ băng ngược lại để chuyển đổi dễ dàng hơn sang số thập phân.

Phần còn lại của mã là:

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

Bảng dịch:

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

l@FBilà tham chiếu: phần tử của hypercube ltại chỉ mục (chuyển đổi itừ nhị phân). Nó xuất hiện thường xuyên, vì vậy chúng tôi gọi nó _và thay thế _bằng mã thực ở cuối.

  • !:_ logic phủ nhận người giới thiệu tại chỗ.

  • --viPU0giảm v(di chuyển con trỏ băng sang phải); sau đó nó đẩy một cái khác 0sang bên trái i, để đảm bảo rằng con trỏ băng nằm trong giới hạn.

  • ++vgia tăng v(không cần kiểm tra giới hạn, mỗi OP).

  • W_{chạy một vòng lặp trong khi người giới thiệu là trung thực (tức là khác không, tức là 1).

  • } đóng vòng lặp.

  • O_ đầu ra người giới thiệu mà không có dòng mới.

Cuối cùng, cho ^:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.