2014-07-21 20 views
6

Vì vậy, tôi đang làm việc trên một chương trình đọc trong một tệp và sau đó xuất lại nó ra nhưng tôi gặp sự cố khi chương trình ngừng tham gia vào kết thúc của tập tin. Tôi muốn nó dừng lại ở một nhân vật cụ thể như '0' hoặc '$' hoặc bất cứ điều gì thực sự kể từ khi một nhân vật NULL không thể được đọc vào thông dịch viên não của tôi. Đây là mã cho đến thời điểm này:Tạo câu lệnh if (x == y) trong Brainfuck

>+[>,][<.] 

Sự cố bắt đầu tại [>,] vì đầu vào không bao giờ có thể là NULL vòng lặp này không bao giờ kết thúc.

Vậy làm cách nào tôi có thể chèn câu lệnh if sẽ chấm dứt vòng lặp này nếu nó đạt đến ký tự kết thúc được chỉ định trước?

Trả lời

5

Mã sau tương đương với mã của bạn, ngoại trừ mã sẽ dừng khi giá trị của đầu vào là 1 (không thể in được bằng ASCII). Các < giữa các vòng được reuired vì giá trị cuối cùng là 0.

>+[+>,-]<[<.] 

Nó decrements giá trị sau khi đầu vào, kiểm tra nếu nó là 0, và lặp lại nếu nó không phải là. Nếu nó lặp lại, nó phải tăng con trỏ một lần nữa để hoàn tác việc giảm. Mảng mẫu có thể là:

00 02 H e l l o _ W o r l d 00 
             ^

Tuy nhiên, [<.] in ngược lại của chuỗi (theo sau là không thể in 1). Chuỗi chính nó có thể được in bằng cách di chuyển con trỏ đến đầu và tiến lên phía trước từ đó, như thể hiện trong mã này:

>+[+>,-]<[<]>>[.>] 

Trong mã này, [<] dừng khi nó đạt đến chỉ số 0, >> di chuyển đến chỉ số 2 (chuỗi bắt đầu), và các ký tự đầu ra [.>] cho đến khi nó đạt đến 0 ở cuối.

Nếu bạn muốn sử dụng ký tự ASCII khác, chẳng hạn như dấu cách (32), lặp lại dấu + và - trong vòng lặp đầu tiên nhiều lần. (Cảnh báo: mã này sẽ dẫn đến các giá trị dưới 0 nếu có bất kỳ ký tự nào nhỏ hơn 32 trong đầu vào của bạn).

>+[++++++++++++++++++++++++++++++++>,--------------------------------]<[<]>>[.>] 
2

Bắt đầu với nhân vật quan trọng của bạn - hãy đi cho $, vì nó ASCII 36:

++++++[->++++++<]> 

đọc đầu vào, sao chép cả đầu vào và các nhân vật đáng kể so với hai lần, với các nhân vật quan trọng thứ hai tại cuối cùng:

[[->+>>>>+<<<<<]>>,[->+>+<<] 

cho một cấu trúc như thế này:

┌───┲━━━━━━━┱───────┬───────┬───┐ 
│ $ ┃ blank ┃ input │ input │ $ │ 
└───┺━━━━━━━┹───────┴───────┴───┘

Subtract là người đầu tiên $ từ input đầu tiên:

<[->>-<<]>> 

Nếu nó không phải là zero, di chuyển về phía trước ba lần vào ô trống sau khi các bản sao của $, sau đó di chuyển về phía sau vô điều kiện, thoát khỏi vòng lặp khi đầu vào là $ và nếu không để lại cho bạn tại một $, sẵn sàng để bắt đầu một lần nữa:

[>>>]<] 

Sau khi vòng lặp, bạn đang rời vào ngày e blank của ký tự phù hợp. Di chuyển tới ký tự đầu vào phù hợp và xóa nó để nó không được in lại, di chuyển ngược lại năm lần để đạt được bản sao còn nguyên vẹn thứ hai đến cuối cùng của input và tiếp tục sao lưu từ đó (điều này không phải dựa vào gói thông dịch viên và như vậy nếu bạn chuyển tiếp một chút ở đầu):

>>[-]<<<<<[<<<<<] 

Và sau đó in chúng ra!

>>>>>[.>>>>>] 

Trong tất cả,

++++++[->++++++<]> 
[[->+>>>>+<<<<<]>>,[->+>+<<]<[->>-<<]>>[>>>]<] 
>>[-]<<<<<[<<<<<]>>>>>[.>>>>>] 
0

Đây là một trang hữu ích đầy đủ của BF algorithms mà tôi muốn tận dụng.

Thuật toán bạn cần là # 19 (x = x==y) và # 28 (if (x) {code}) hoặC# 30 (if (x) {code1} else {code2}).

Kiểm tra xem hai ô bằng nhau có khá dễ dàng không, vì vậy tôi sẽ chỉ sao chép thuật toán if (x) {code1} else {code2} tại đây. temp0 có nghĩa là di chuyển đến một ô để sử dụng như một biến tạm thời. Mã cụ thể này yêu cầu rằng temp0temp1 theo dõi x liên tiếp trong bộ nhớ.

temp0[-]+ 
temp1[-] 
x[ 
code1 
x>-]> 
[< 
code2 
x>->]<< 
Các vấn đề liên quan