Tạo Brainf *** NOP


26

Đôi khi khi viết mã brainfuck, bạn cảm thấy cần phải làm cho nó dài hơn mức cần thiết để khuyến khích gỡ lỗi. Bạn có thể làm điều đó bằng cách chỉ cần ngồi một chỗ ><trong đó, nhưng có gì vui? Bạn sẽ cần một cái gì đó dài hơn và ít NOPey để gây nhầm lẫn cho bất kỳ ai đọc mã của bạn.

Giới thiệu nhanh về Brainfuck

Brainfuck là một ngôn ngữ lập trình bí truyền được tạo ra vào năm 1993 bởi Urban Müller, và đáng chú ý vì sự tối giản cực độ của nó. (Wikipedia)

Brainfuck là một ngôn ngữ dựa trên tám lệnh : +-><,.[]. Mã được chạy trên một cái gì đó giống như một máy Turing: một băng vô hạn mà các giá trị có thể được thay đổi. Trong thử thách này, chúng tôi sẽ tập trung vào bốn người đầu tiên:

+    increment the value at the pointer
-    decrement the value at the pointer
>    move the pointer right
<    move the pointer left

NOP Brainfuck

NOP brainfuck là một chuỗi các nhân vật brainfuck, khi được thực hiện từ bất kỳ trạng thái nào, dẫn đến không có thay đổi trong trạng thái. Chúng bao gồm bốn nhân vật được đề cập ở trên.

Các thách thức

Thách thức là viết một chương trình hoặc chức năng mà khi được thực thi sẽ tạo ra một NOP ngẫu nhiên có độ dài nhất định.

Đầu vào

Bạn sẽ nhận được như là một số nguyên chẵn không âm n. (NOP là không thể cho lẻ n.)

Đầu ra

Bạn sẽ tạo ra một NOP brainfuck ngẫu nhiên về độ dài n.

Quy tắc

  • Định nghĩa của NOP: khi đầu ra của chương trình được chèn tại bất kỳ điểm nào trong chương trình brainfuck, hành vi của chương trình đã nói không được thay đổi theo bất kỳ cách nào. Nói cách khác, nó không được thay đổi trạng thái của trình thông dịch.
    • Lưu ý rằng ví dụ +>-<là không chính xác, vì nó thay đổi giá trị của hai ô mà không thay đổi chúng trở lại. Vui lòng kiểm tra giải pháp của bạn cho những điều này trước khi đăng.
    • Cũng lưu ý rằng đó +>-<->+<là một NOP không thể giảm xuống chỉ bằng cách xóa >< <> +- -+. Vì vậy, bạn không thể sử dụng một thuật toán chỉ chèn những cái này vào nhau.
  • Mỗi NOP hợp lệ của độ dài nphải có cơ hội khác không xuất hiện trong đầu ra. Việc phân phối không phải là thống nhất, mặc dù.
  • Trình thông dịch brainfuck trong câu hỏi có một băng gấp đôi vô hạn của các tế bào chính xác tùy ý. Nghĩa là, bạn có thể đi vô tận cả hai hướng và tăng / giảm từng ô một cách vô thời hạn.
  • Chương trình phải hoàn thành trong vòng 1 phút cho n= 100 trên máy của tôi, vì vậy không tạo ra tất cả các NOP có thể và chọn một NOP.
  • Nếu được cung cấp đầu vào không hợp lệ (không nguyên, âm, lẻ, v.v.), bạn có thể làm bất cứ điều gì bạn muốn, bao gồm cả sự cố.

Chấm điểm

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

Ví dụ

Dưới đây là tất cả các kết quả đầu ra hợp lệ cho n= 4:

++--    +-+-    +--+    --++    -+-+    -++-
>><<    ><><    ><<>    <<>>    <><>    <>><
><+-    ><-+    <>+-    <>-+
>+-<    >-+<    <+->    <-+>
+><-    -><+    +<>-    -<>+
+-><    -+><    +-<>    -+<>

Dưới đây là một vài kết quả đầu ra có thể cho n= 20:

+>>->+<->-<<<->>++<<
>+>-<+<->+-<>->+<-<+
+--+-++--++-+--+-++-
>>>>>>>>>+-<<<<<<<<<

18
đây là một NOP Brainfuck mà không sử dụng +-<>như bạn yêu cầu:a
undergroundmonorail

1
Tôi không nghĩ rằng NOP không đơn giản tồn tại, vì vậy bạn có thể loại bỏ trình độ đó. .có tác dụng phụ, ,ghi đè lên một giá trị không thể phục hồi mà không sử dụng []. Nhưng []cuối cùng sẽ thiết lập một giá trị bằng không. Điều này cũng ghi đè lên một giá trị (vì vậy chúng tôi cần một giá trị khác []để khôi phục nó) trừ khi chúng tôi có thể chắc chắn rằng ô bị ảnh hưởng là 0 để bắt đầu. Tuy nhiên, chúng tôi phải tìm kiếm một tế bào như vậy với một cái gì đó tương tự [>], và không thể quay trở lại vị trí mà chúng tôi đến một cách đáng tin cậy.
Martin Ender

4
@Eumel "Trình thông dịch brainfuck trong câu hỏi có một băng gấp đôi vô hạn của các tế bào chính xác tùy ý."
Martin Ender

2
Xin lưu ý rằng "Brainfuck" không còn được phép trong các tiêu đề câu hỏi ở cấp hệ thống. Dường như bạn có thể tránh được sự hạn chế bằng cách sử dụng các ký tự không phải ASCII. Trong tương lai, xin vui lòng tuân theo hạn chế này.
Alex A.

2
@undergroundmonorail Chà, nó hoàn thành Turing ... vì vậy về mặt kỹ thuật người ta có thể viết PRNG bằng nó giống như bất kỳ ngôn ngữ nào khác. (Mặc dù gieo hạt có thể khó.)
PurkkaKoodari

Câu trả lời:


13

CJam, 62 59 byte

Cảm ơn nhahtdh vì đã tiết kiệm 3 byte.

Do không có yêu cầu đối với bất kỳ phân phối cụ thể nào, miễn là mỗi no-op xuất hiện với xác suất hữu hạn, chúng tôi có thể đơn giản hóa điều này rất nhiều bằng cách tạo chuỗi chứa số lượng cân bằng -+<>, tương ứng, kiểm tra nếu đó là NOP và sắp xếp nó nếu nó không phải.

Tất nhiên, đối với các đầu vào dài hơn, điều này hầu như sẽ luôn dẫn đến đầu ra được sắp xếp, nhưng bạn có thể kiểm tra mã với một số đầu vào như 8để thấy rằng về nguyên tắc nó có thể tạo ra bất kỳ NOP nào có độ dài cho trước.

ri_0a*\2/{;"-+<>":L2/mR}%smr:SL["Xa.Xm"3/2e*L]z:sers~0-S$S?

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


1
Có ... giới hạn tùy ý nên là n = 1000 dưới 10 giây. Máy tính chỉ là cách để nhanh chóng ngày hôm nay ^^ Bởi vì câu trả lời thuật toán giải quyết nó trong một giây thậm chí cho n = 1000
Falco

Đối với n lớn hơn nữa, tôi nghĩ có thể chỉ sắp xếp đầu ra nếu chuỗi cân bằng không phải là NOP. Phân phối bị sai lệch khủng khiếp, nhưng câu hỏi được cho phép.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ đó là một ý tưởng gọn gàng.
Martin Ender

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Cảm ơn, điều đó thực sự cũng tiết kiệm ba byte ở đây.
Martin Ender

16

CJam, 118 116 byte

Điều này hơi ngoài tầm tay ... đặc biệt là hiệp hai có vẻ như rất đáng chơi.

ri2/_)mr:R-"<>"R*mr_'=fm0\{1$+}%+__&e`]:\{mr1aa..+}*\@](\z:~\{~\("+-"*mr1$3$e=[{_,)mr_2$<@@>}*+]@@f{`1$`={(}@?\}W<}/

Kiểm tra nó ở đây.

Điều này xử lý N = 100khá nhiều ngay lập tức. Bây giờ tôi không có thời gian để viết toàn bộ mã, vì vậy đây là thuật toán:

  • Tạo một chuỗi cân bằng ngẫu nhiên <>có độ dài ngẫu nhiên (chẵn) giữa 0Nbao gồm.
  • Riffle các vị trí đầu băng vào mảng này. Ví dụ "<>><"trở thành [0 '< -1 '> 0 '> 1 '< 0].
  • Lấy danh sách tất cả các vị trí đạt được trong quá trình.
  • Đối với mỗi vị trí như vậy khởi tạo một chuỗi rỗng. Cũng xác định có bao nhiêu cặp ký tự còn lại để đạt được một chuỗi độ dài N.
  • Đối với mỗi cặp còn lại sẽ nối +-vào chuỗi của một vị trí ngẫu nhiên.
  • Xáo trộn tất cả các chuỗi.
  • Đối với mỗi vị trí xác định tần suất vị trí đó xảy ra trong mảng được đánh dấu và chia chuỗi tương ứng thành nhiều đoạn (độ dài ngẫu nhiên).
  • Trong mảng được đánh dấu, thay thế các lần xuất hiện của vị trí bằng các khối ngẫu nhiên của nó.

Làm xong. Điều này dựa trên sự quan sát rằng:

  • Bất kỳ NOP nào cũng phải có số lượng bằng nhau <>để trả đầu băng về vị trí ban đầu.
  • Mã sẽ là một NOP miễn là mỗi ô băng được tăng lên thường xuyên như giảm dần.

Bằng cách phân phối số lượng +s và -s ngẫu nhiên nhưng cân bằng giữa tất cả các vị trí mà đầu băng nằm trên một ô đã cho, chúng tôi đảm bảo rằng chúng tôi tìm thấy mọi NOP có thể.


4

Toán học, 350 byte

Quiet@(For[a="+",If[{##4}=={},#3!=0||Union@#!={0},Switch[#4,"+",#0[ReplacePart[#,#2->#[[#2]]+1],#2,#3,##5],"-",#0[ReplacePart[#,#2->#[[#2]]-1],#2,#3,##5],">",#0[#~Append~0,#2+1,#3+1,##5],"<",If[#2<2,#0[#~Prepend~0,1,#3-1,##5],#0[#,#2-1,#3-1,##5]]]]&@@{{0},1,0}~Join~Characters@a,a=""<>RandomSample@Flatten@RandomChoice[{{"+","-"},{">","<"}},#/2]];a)&

Con đường quá dài? Vâng. Tôi có quan tâm không? Không phải cho đến khi người khác đăng một câu trả lời hợp lệ.


4
Bạn có phiền khi thêm một lời giải thích, để mọi người thực sự có thể thuyết phục bản thân điều này là hợp lệ? :)
Martin Ender

Làm thế nào một cách chính xác làm công việc này? Nếu tôi gọi hàm với một số thì nó chỉ trả về +.
Martin Ender

@ MartinBüttner cố định ... Hiện nay, nó chỉ tạo ra các chương trình ngẫu nhiên với một số lượng tương đương +- -<- >cặp cho đến khi một sẽ xảy ra là một NOP. Một nửa trong số đó được thực hiện bởi một thông dịch viên BF đơn giản.
LegionMammal978

điều đó thực sự tạo ra một no-op hợp lệ có độ dài 100 trong dưới một phút?
Martin Ender

@ MartinBüttner Có. Trung bình, tôi sẽ nói rằng mất khoảng 5 giây. Lúc đầu, tôi đã thử các chương trình hoàn toàn ngẫu nhiên, nhưng nó không bao giờ chấm dứt trong thời gian 100.
LegionMammal978

2

Python 3 , 177 byte

from random import*
n=int(input())
r=[0]*n*3
p=0
a=[43,45]
s=choices(a+[60,62],k=n)
for c in s:p+=~c%2*(c-61);r[p]+=c%2*(44-c)
if any(r+[p]):s=a*(n//2)
print(*map(chr,s),sep='')

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

Tôi đã sử dụng mã từ câu trả lời của Bubbler cho mô phỏng BF.


2

Python 3 , 163 byte

from random import*
n=int(input())
p=0;d=[0]*n;a=choices(b'+-<>',k=n)
for c in a:d[p]+=c%2*(44-c);p+=~c%2*(c-61)
if p|any(d):a=n//2*b'+-'
print(*map(chr,a),sep='')

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

Chương trình đầy đủ in kết quả sang STDOUT. Dòng chạy mã BF có thể chơi được.

Thông qua cách tiếp cận của Tyilo; nếu mã BF được tạo không phải là NOP, hãy loại bỏ nó hoàn toàn và quay lại '+-'lặp lại.


Thời gian chờ cho n = 100
l4m2

@ l4m2 Không nhận thấy yêu cầu đó. Đã sửa.
Bong bóng


1

Ngôn ngữ Wolfram (Mathicala) , 224 byte

(s=RandomSample[##&@@@Table["<"">",(r=RandomInteger)[#/2]]];While[(g=Length@s)<#,s=Insert[s=Insert[s,"+",i=r@g+1],"-",RandomChoice@@Select[GatherBy[0~Range~++g,Count[#,"<"]-Count[#,">"]&@Take[s,#]&],!FreeQ[#,i]&]+1]];""<>s)&

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

Đây là phiên bản chưa được đánh gôn (hay đúng hơn là chơi trước):

Function[{n},
 k = RandomInteger[n/2];
 s = RandomSample[## & @@@ Table["<" ">", k]];
 While[Length[s] < n,
   s = Insert[s, "+", i = RandomInteger[Length[s]] + 1];
   p = GatherBy[Range[0, Length[s]], 
     Count[#, "<"] - Count[#, ">"]& @ Take[s, #]&];
   j = RandomChoice @@ Select[p, ! FreeQ[#, i] &]];
   s = Insert[s, "-", j + 1];
   ];
 ""<>s]

Trước tiên, chúng tôi chọn một số ngẫu nhiên <>để sử dụng và tạo một danh sách ngẫu nhiên với số lượng bằng nhau.

Để điền vào các ký tự còn lại, chúng tôi chọn một vị trí để thêm a +, sau đó tìm một vị trí nơi con trỏ trỏ đến cùng một vị trí và thêm một vị trí -ở đó.

Lặp lại cho đến khi danh sách có độ dài nvà xâu chuỗi kết quả.

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.