ตีความสมอง ***


113

เขียนโปรแกรมที่สั้นที่สุดในภาษาที่คุณชื่นชอบเพื่อตีความโปรแกรมbrainfuck โปรแกรมอ่านจากไฟล์ อินพุตและเอาต์พุตเป็นอินพุตมาตรฐานและเอาต์พุตมาตรฐาน

  1. ขนาดของเซลล์: 8 บิตที่ไม่ได้ลงชื่อ โอเวอร์โฟลว์ไม่ได้กำหนด
  2. ขนาดอาร์เรย์: 30000 ไบต์ (ไม่วน)
  3. คำสั่งที่ไม่ถูกต้องไม่ได้เป็นส่วนหนึ่งของอินพุต
  4. ความคิดเห็นเริ่มต้นด้วย # และขยายไปถึงจุดสิ้นสุดความคิดเห็นคือทุกอย่างที่ไม่ได้อยู่ใน+-.,[]<>
  5. ไม่มีสัญลักษณ์ EOF

การทดสอบที่ดีมากสามารถพบได้ที่นี่ มันอ่านตัวเลขแล้วพิมพ์จำนวนเฉพาะถึงจำนวนนั้น เพื่อป้องกันไม่ให้ลิงค์เน่านี่คือสำเนาของรหัส:

compute prime numbers
to use type the max number then push Alt 1 0
===================================================================
======================== OUTPUT STRING ============================
===================================================================
>++++++++[<++++++++>-]<++++++++++++++++.[-]
>++++++++++[<++++++++++>-]<++++++++++++++.[-]
>++++++++++[<++++++++++>-]<+++++.[-]
>++++++++++[<++++++++++>-]<+++++++++.[-]
>++++++++++[<++++++++++>-]<+.[-]
>++++++++++[<++++++++++>-]<+++++++++++++++.[-]
>+++++[<+++++>-]<+++++++.[-]
>++++++++++[<++++++++++>-]<+++++++++++++++++.[-]
>++++++++++[<++++++++++>-]<++++++++++++.[-]
>+++++[<+++++>-]<+++++++.[-]
>++++++++++[<++++++++++>-]<++++++++++++++++.[-]
>++++++++++[<++++++++++>-]<+++++++++++.[-]
>+++++++[<+++++++>-]<+++++++++.[-]
>+++++[<+++++>-]<+++++++.[-]

===================================================================
======================== INPUT NUMBER  ============================
===================================================================
+                          cont=1
[
 -                         cont=0
 >,
 ======SUB10======
 ----------

 [                         not 10
  <+>                      cont=1
  =====SUB38======
  ----------
  ----------
  ----------
  --------

  >
  =====MUL10=======
  [>+>+<<-]>>[<<+>>-]<     dup

  >>>+++++++++
  [
   <<<
   [>+>+<<-]>>[<<+>>-]<    dup
   [<<+>>-]
   >>-
  ]
  <<<[-]<
  ======RMOVE1======
  <
  [>+<-]
 ]
 <
]
>>[<<+>>-]<<

===================================================================
======================= PROCESS NUMBER  ===========================
===================================================================

==== ==== ==== ====
numd numu teid teiu
==== ==== ==== ====

>+<-
[
 >+
 ======DUP======
 [>+>+<<-]>>[<<+>>-]<

 >+<--

 >>>>>>>>+<<<<<<<<   isprime=1

 [
  >+

  <-

  =====DUP3=====
  <[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<<<

  =====DUP2=====
  >[>>+>+<<<-]>>>[<<<+>>>-]<<< <


  >>>


  ====DIVIDES=======
  [>+>+<<-]>>[<<+>>-]<   DUP i=div

  <<
  [
    >>>>>+               bool=1
    <<<
    [>+>+<<-]>>[<<+>>-]< DUP
    [>>[-]<<-]           IF i THEN bool=0
    >>
    [                    IF i=0
      <<<<
      [>+>+<<-]>>[<<+>>-]< i=div
      >>>
      -                  bool=0
    ]
    <<<
    -                    DEC i
    <<
    -
  ]

  +>>[<<[-]>>-]<<          
  >[-]<                  CLR div
  =====END DIVIDES====


  [>>>>>>[-]<<<<<<-]     if divides then isprime=0


  <<

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

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

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

  >>




  ===================================================================
  ======================== OUTPUT NUMBER  ===========================
  ===================================================================
  [>+<-]>

  [
   ======DUP======
   [>+>+<<-]>>[<<+>>-]<


   ======MOD10====
   >+++++++++<
   [
    >>>+<<              bool= 1
    [>+>[-]<<-]         bool= ten==0
    >[<+>-]             ten = tmp
    >[<<++++++++++>>-]  if ten=0 ten=10
    <<-                 dec ten     
    <-                  dec num
   ]
   +++++++++            num=9
   >[<->-]<             dec num by ten

   =======RROT======
      [>+<-]
   <  [>+<-]
   <  [>+<-]
   >>>[<<<+>>>-]
   <

   =======DIV10========
   >+++++++++<
   [
    >>>+<<                bool= 1
    [>+>[-]<<-]           bool= ten==0
    >[<+>-]               ten = tmp
    >[<<++++++++++>>>+<-] if ten=0 ten=10  inc div
    <<-                   dec ten     
    <-                    dec num
   ]
   >>>>[<<<<+>>>>-]<<<<   copy div to num
   >[-]<                  clear ten

   =======INC1=========
   <+>
  ]

  <
  [
   =======MOVER=========
   [>+<-]

   =======ADD48========
   +++++++[<+++++++>-]<->

   =======PUTC=======
   <.[-]>

   ======MOVEL2========
   >[<<+>>-]<

   <-
  ]

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

  ===================================================================
  =========================== END FOR ===============================
  ===================================================================


  >>>>>>>
 ]
 <<<<<<<<



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

======LF========

++++++++++.[-]
@

ตัวอย่างการเรียกใช้:

$ python2 bf.py PRIME.BF 
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 

5
คุณควรอธิบายให้ชัดเจนเกี่ยวกับ 1) ขนาดของหน่วยความจำ 2) เป็นหน่วยความจำที่วนเป็นวงกลม 4) อาจมีรายละเอียด
Nakilon

3
ฉันสงสัยว่าควรมีสองประเภทหรือไม่: โปรแกรมเหล่านั้นที่ใช้ eval (หรือใช้ shell เพื่อคอมไพล์) - และโปรแกรมที่ไม่ทำ
MtnViewMark

34
ฉันชอบที่จะเห็นคนตอบคำถามนี้ใน brainfuck
Hannesh

3
"ไม่มีสัญลักษณ์ EOF" หมายความว่าอะไร? ว่าค่าของเซลล์ยังคงไม่เปลี่ยนแปลงเมื่อพยายาม,EOF? หรือว่ามันขึ้นอยู่กับเราที่จะเลือกค่าเมื่อลอง,ใช้ EOF หรือ EOF ไม่ได้กำหนดพฤติกรรมทั้งหมดหรือไม่
Martin Ender

3
เช่นเดียวกันจะเกิดอะไรขึ้นเมื่อมีคนพยายามทิ้งเซลล์ 30k ไว้ด้านใดด้านหนึ่ง? ควรหัวเทปอยู่ในตำแหน่งหรือเป็นพฤติกรรมที่ไม่ได้กำหนดนี้?
Martin Ender

คำตอบ:


46

Perl, 120 138

%c=qw(> $p++ < $p-- + D++ - D-- [ while(D){ ] } . print+chrD , D=ord(getc));
$/=$,;$_=<>;s/./$c{$&};/g;s[D]'$b[$p]'g;eval

สิ่งนี้รัน hello.bf และ primes.bf อย่างไม่มีที่ติ:

$ perl bf.pl hello.bf
Hello World!
$ perl bf.pl prime.bf
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

เริ่มต้นที่: opcode ไปที่ตารางการแปล Perl %cถูกเก็บไว้ใน แบบฟอร์มที่อ่านได้มีลักษณะดังนี้:

%c=(
  '>' => '$p++',
  '<' => '$p--',
  '+' => '$b[$p]++',
  '-' => '$b[$p]--',
  '[' => 'while($b[$p]){',
  ']' => '}',
  '.' => 'print chr$b[$p]',
  ',' => '$b[$p]=ord(getc)',
);

ขั้นตอนที่ 1: Slurp โปรแกรมอินพุต$_และแปลงเป็นโค้ด Perl โดยใช้ตารางการแปล ความคิดเห็นจะถูกปล้นโดยอัตโนมัติ (แทนที่ด้วยundef) ในขั้นตอนนี้

ขั้นตอนที่ 2: คลายการบีบอัดข้อมูลที่$b[$p]เกิดขึ้นทั้งหมด

ขั้นตอนที่ 3: evalเปิดโปรแกรมโดยใช้


เพียงใช้qwไวยากรณ์ของ Perl เพื่อกำหนด%cโดยตรง - ดีสำหรับ 7 ตัวอักษรที่น้อยกว่า (คุณจะต้องพูดprint+chr$b[$p]และord(getc))
ม็อบ

ฉันนับจำนวนที่บันทึกไว้ 18 แล้ว…ขอบคุณ! (อัปเดตในอีกไม่กี่นาที)
JB

1
@ olivecoder คุณกำลังพูดถึงอะไรในโลก?
JB

ตาราง% c ถูกประกาศและกำหนดไว้ในบรรทัดแรก มันเป็นตัวละครที่สมบูรณ์แบบ
JB

@JB เฮ้ฉันกดลงคะแนนโดยไม่ตั้งใจสำหรับคำตอบของคุณและมันถูกล็อคคุณสามารถแก้ไขได้เพื่อที่ฉันจะสามารถย้อนกลับโหวตลงได้หรือไม่?
Cyclohexanol

67

Python (ไม่มีรูปแบบ), 317 ไบต์

from sys import*
def f(u,c,k):
 while(c[1]>=k)*u:
  j,u='[]<>+-,.'.find(u[0]),u[1:];b=(j>=0)*(1-j%2*2);c[1]+=b*(j<2)
  while b*c[c[0]]and j<1:f(u,c,k+1);c[1]+=1
  b*=c[1]==k;c[[0,c[0],2][j/2-1]]+=b
  if(j==6)*b:c[c[0]]=ord(stdin.read(1))
  if(j>6)*b:stdout.write(chr(c[c[0]]))
f(open(argv[1]).read(),[-1]+[0]*30003,0)

70
+1 สำหรับf(u,c,k)
Joel Cornett

9
นั่นคือเสียงที่สวยงามชิ้นเดียว, คุณ
globby

-1 ไบต์ถ้าคุณแทนที่while b*c[c[0]]and j<1ด้วยwhile b*c[c[0]]*(j<1)
Daniil Tutubalin

50

รหัสเครื่อง 16 บิต 8086: 168 ไบต์

นี่คือเวอร์ชันที่เข้ารหัสbase64แปลงและบันทึกเป็น 'bf.com' และเรียกใช้จากพรอมต์คำสั่ง Windows: 'bf progname'

gMYQUoDGEFKzgI1XAgIfiEcBtD3NIR8HcmOL2LQ/i88z0s0hcleL2DPA86sz/zP2/sU783NHrL0I
AGgyAU14DTqGmAF194qOoAH/4UfDJv4Fwyb+DcO0AiaKFc0hw7QBzSGqT8MmODV1+jPtO/NzDaw8
W3UBRTxddfJNee/DJjg1dPoz7U509YpE/zxddQFFPFt18U157sM+PCstLixbXUxjTlJWXmV+

แก้ไข

นี่คือแอสเซมเบลอร์บางส่วน (สไตล์ A86) เพื่อสร้างไฟล์เรียกทำงาน (ฉันต้องทำวิศวกรรมย้อนกลับเพราะฉันใส่ผิดแหล่งต้นฉบับ!)

    add dh,10h                              
    push dx                                 
    add dh,10h                              
    push dx                                 
    mov bl,80h                              
    lea dx,[bx+2]                         
    add bl,[bx]                            
    mov [bx+1],al                         
    mov ah,3dh                              
    int 21h                                 
    pop ds                                 
    pop es                                 
    jb ret                               
    mov bx,ax                              
    mov ah,3fh                              
    mov cx,di                              
    xor dx,dx                              
    int 21h                                 
    jb ret                               
    mov bx,ax                              
    xor ax,ax                              
    repz stosw                                     
    xor di,di                              
    xor si,si                              
    inc ch                                 
program_loop:
    cmp si,bx                              
    jnb ret                               
    lodsb                                    
    mov bp,8                            
    push program_loop
symbol_search:                       
    dec bp                                 
    js ret
    cmp al,[bp+symbols]
    jnz symbol_search
    mov cl,[bp+instructions]
    jmp cx                                 
forward:
    inc di                                 
    ret                                    
increment:
    inc b es:[di]                      
    ret                                    
decrement:
    dec b es:[di]                      
    ret                                    
output:
    mov ah,2                              
    mov dl,es:[di]                            
    int 21h                                 
    ret                                    
input:
    mov ah,1                              
    int 21h                                 
    stosb                                    
backward:
    dec di                                 
    ret                                    
jumpforwardifzero:
    cmp es:[di],dh                            
    jnz ret                               
    xor bp,bp
l1: cmp si,bx                              
    jnb ret
    lodsb                                    
    cmp al,'['                              
    jnz l2
    inc bp
l2: cmp al,']'                              
    jnz l1
    dec bp                                 
    jns l1
    ret                                    
jumpbackwardifnotzero:
    cmp es:[di],dh                            
    jz  ret
    xor bp,bp
l3: dec si                                 
    jz  ret
    mov al,[si-1]                         
    cmp al,']'
    jnz l4
    inc bp  
l4: cmp al,'['                              
    jnz l3
    dec bp                                 
    jns l3
    ret                                    
symbols:
    db '><+-.,[]'
instructions:
    db forward and 255
    db backward and 255
    db increment and 255
    db decrement and 255
    db output and 255
    db input and 255
    db jumpforwardifzero and 255
    db jumpbackwardifnotzero and 255

ฉันได้เพิ่มเวอร์ชันซอร์สโค้ดของโปรแกรม ฉันเพิ่งสังเกตเห็นว่าตัวละครที่ไม่ใช่ BF ทำให้โปรแกรมออกจากแทนที่จะถูกละเว้น ง่ายต่อการแก้ไขและฉันจะปล่อยให้มันเป็นแบบฝึกหัดสำหรับคนที่จะทำเอง
Skizz

ฉันจำได้ว่าฉันได้รับ Linux ELF เวอร์ชัน 166 ไบต์เมื่อ 10 ปีที่แล้วที่นี่muppetlabs.com/~breadbox/software/tiny
Emmanuel

39

brainfuck , 843 691 ไบต์

แก้ไข: ตัดสินใจกลับมาใหม่และพบวิธีที่น่าแปลกใจในการตีไบต์จำนวนมาก

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

ซึ่งจะป้อนข้อมูลในแบบฟอร์มcode!inputที่!inputเป็นตัวเลือก มันยังจำลองเซลล์เชิงลบโดยไม่ต้องใช้เซลล์เชิงลบเองและสามารถเก็บได้ถึง(30000-(length of code+6))/2เซลล์

ลองออนไลน์!


เพียงเพื่อให้แน่ใจว่าฉันได้รับสิทธิ์นี้หากฉันใช้โปรแกรมนี้กับโปรแกรมนี้ฉันสามารถซ้อนได้ 5 ระดับและยังคงจัดการกับรหัสอินพุตความยาว 262
Draco18s

@ Draco18s ฉันสงสัยว่าคุณจะใช้งานเซลล์ 30000 ก่อนหน้านั้นเนื่องจากขนาดของล่ามซ้อนกันเพิ่มขึ้นเป็นทวีคูณ ฉันคิดว่าคุณจะได้ 2 หรือ 3 ระดับลึก
โจคิง

แม้กระทั่ง 3 ลึกก็จะเป็นเรื่องตลกเฮฮา
Draco18s

27

Ruby 1.8.7, 188 185 149 147 ตัวอักษร

eval"a=[i=0]*3e4;"+$<.bytes.map{|b|{?.,"putc a[i]",?,,"a[i]=getc",?[,"while a[i]>0",?],"end",?<,"i-=1",?>,"i+=1",?+,"a[i]+=1",?-,"a[i]-=1"}[b]}*";"

รุ่นที่สามารถอ่านได้ค่อนข้าง:

code = "a = [0] * 3e4; i = 0;"
more_code ARGF.bytes.map {|b|
  replacements = {
    ?. => "putc a[i]",
    ?, => "a[i] = getc",
    ?[ => "while a[i] > 0 do",
    ?] => "end",
    ?< => "i -= 1",
    ?> => "i += 1",
    ?+ =>"a[i]+=1",
    ?- =>"a[i]-=1"
  }
  replacements[b]
}.join(";")
eval code+more_code

อย่างที่คุณเห็นฉันขโมยความคิดของคุณเกี่ยวกับการแปลเป็นภาษาโฮสต์และใช้ eval เพื่อเรียกใช้มัน


คุณสามารถโกนไบต์ไบต์เปรียบเทียบกับศูนย์มากกว่าการทดสอบความเท่าเทียมกัน:>0 !=0รายละเอียดบอกว่าไม่ได้ลงชื่อและล้นไม่ได้กำหนด
คนขี้ขลาดนิรนาม

3e4จะทำงานเมื่อเทียบกับ30000
คนขี้ขลาดนิรนาม

@ Charlie: ขอบคุณ แม้ว่าจะยุติธรรม แต่ก็ไม่ได้พูดว่า "ไม่ได้ลงนาม" เมื่อฉันเขียนรหัส ฉันก็ไม่รู้เหมือนกันว่าคุณสามารถเขียน 3e4 ได้ นั่นเป็นจุดที่ดีมากและเป็นเรื่องน่ารู้
sepp2k

File.read($*.pop).bytes-> $<.bytesควรทำงานด้วย
Arnaud Le Blanc

1
ทับทิม 1.8.7 มีไวยากรณ์แม้สั้นที่จะสร้างกัญชาอักษร: ซึ่งเทียบเท่ากับ{?a,"foo"} {?a=>"foo"}และการทดสอบที่นี่แสดงให้เห็นว่าคุณสามารถแทนที่File.read($*.pop).bytesด้วยจริงๆ$<โดยไม่มีปัญหาใด ๆ ยังฝังทุกสิ่งเข้ากับบางสิ่งบางอย่างเช่นeval"a[0]..."+$<.bytes.map{?.,"putc a[i]",...}*";"ทำให้การแก้ปัญหาสั้นลงด้วยตัวละครอีกสองสามตัว
Ventero

26

ไบนารีแลมบ์ดาแคลคูลัส 112

โปรแกรมที่แสดงในฐานสิบหกด้านล่าง

00000000  44 51 a1 01 84 55 d5 02  b7 70 30 22 ff 32 f0 00  |DQ...U...p0".2..|
00000010  bf f9 85 7f 5e e1 6f 95  7f 7d ee c0 e5 54 68 00  |....^.o..}...Th.|
00000020  58 55 fd fb e0 45 57 fd  eb fb f0 b6 f0 2f d6 07  |XU...EW....../..|
00000030  e1 6f 73 d7 f1 14 bc c0  0b ff 2e 1f a1 6f 66 17  |.os..........of.|
00000040  e8 5b ef 2f cf ff 13 ff  e1 ca 34 20 0a c8 d0 0b  |.[./......4 ....|
00000050  99 ee 1f e5 ff 7f 5a 6a  1f ff 0f ff 87 9d 04 d0  |......Zj........|
00000060  ab 00 05 db 23 40 b7 3b  28 cc c0 b0 6c 0e 74 10  |....#@.;(...l.t.|
00000070

คาดว่าอินพุตจะประกอบด้วยโปรแกรม Brainfuck (ดูที่บิต 0,1,4 เพื่อแยกความแตกต่างระหว่าง, -. + <>] [) ตามด้วย], ตามด้วยอินพุตสำหรับโปรแกรม Brainfuck

บันทึกดัมพ์ hex ข้างต้นด้วย xxd -r> bf.Blc

หยิบล่าม blc จากhttps://tromp.github.io/cl/cl.html

cc -O2 -DM=0x100000 -m32 -std=c99 uni.c -o uni
echo -n "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.]" > hw.bf
cat bf.Blc hw.bf | ./uni

สวัสดีชาวโลก!


1
ทำไมสิ่งนี้ถึงมีอยู่จริง? เห็นได้ชัดว่ามันยังอยู่ในขอบเขตของการวิจัย Oo
Isiah Meadows

ดังนั้นสิ่งนี้จะไม่ทำงานกับโปรแกรม brainfuck ที่มีความคิดเห็นใช่ไหม
kamoroso94

ไม่ไม่แยกความคิดเห็นออกก่อน
John Tromp

18

เรติน่า 0.8.2 , 386 391 386 ไบต์

รหัสประกอบด้วยอักขระ NUL ( 0x00) ที่ไม่สามารถพิมพ์ได้ มันยังไม่ได้เป็นสนามกอล์ฟที่ยอดเยี่ยมเพราะมันช้าแล้วและถ้าฉันตีมันมากกว่านี้ฉันก็ไม่รู้ว่ามันจะใช้เวลานานแค่ไหน ดูเหมือนจะหมดเวลากับตัวอย่างที่หาได้ยาก

อาจมีข้อบกพร่องในล่ามออนไลน์หรือในโปรแกรมของฉัน (บรรทัดใหม่นำไม่แสดงในผลลัพธ์หรือไม่)

<code>│<input>จะเข้าเช่น ไม่นั่นไม่ใช่ท่อ ( |) U+2502มันเป็นอักขระ Unicode ÿ▶◀├║รหัสยังใช้ตัวอักษร Unicode อักขระ Unicode ถูกใช้เพื่อสนับสนุนอินพุตของอักขระ ASCII ทั้งหมด ดังนั้นอักขระเหล่านี้จำเป็นต้องแยกออกจากรหัสด้วยอักขระที่ไม่ใช่ ASCII

ลองออนไลน์

s`^.*
▶$0├║▶
s{`(▶>.*║.*)▶(.)(.?)
$1$2▶$3
▶$
▶
║▶
║▶
(▶<.*║.*)(.)▶
$1▶$2
T`ÿ-`o`(?<=▶\+.*║.*▶).
^\+

T`-ÿ`ÿo`(?<=▶-.*║.*▶).
^-

(▶\..*├.*)(║.*▶)(.)
$1$3$2$3
(▶,.*│)(.?)(.*├.*▶).
$1$3$2
▶\[(.*║.*▶)
[▶▶${1}
{`(▶▶+)([^[\]]*)\[
$2[$1▶
}`▶(▶+)([^[\]]*)\]
$2]$1
r`([[\]]*)▶\](.*║.*▶[^])
$1◀◀]$2
r{`\[([^[\]]*)(◀+)◀
$2[$1
}`\]([^[\]]*)(◀◀+)
$2◀]$1
◀
▶
}`▶([^│])(.*║)
$1▶$2
s\`.*├|║.*

โปรดทราบว่ามีการขึ้นบรรทัดใหม่ที่ส่วนท้าย

คำอธิบายสั้น ๆ :

เลขศูนย์0x00ใช้สำหรับเทปซึ่งไม่มีที่สิ้นสุด การแทนที่ครั้งแรกจะเป็นการตั้งค่าล่ามในรูปแบบ▶<code>│<input>├<output>║▶<tape>โดยที่ตัวแรกคือตัวชี้สำหรับรหัสและตัวที่สองคือตัวชี้สำหรับเทป

ÿคือ0xFF(255) ซึ่งใช้สำหรับการทับศัพท์ (ใช้เพื่อนำไปใช้+และ-) เพื่อตัดเซลล์กลับเป็นศูนย์

ใช้สำหรับความสามารถในการอ่านเท่านั้น (ในกรณีที่โปรแกรมหยุดกลางหรือคุณต้องการเห็นโปรแกรมทำงานกลางคัน) ไม่เช่นนั้นคุณไม่สามารถบอกได้ว่าตัวชี้เคลื่อนไหวไปทางไหน

รหัสความคิดเห็น:

s`^.*                       # Initialize
▶$0├║▶
s{`(▶>.*║.*)▶(.)(.?)        # >
$1$2▶$3
▶$
▶
║▶                          # <
║▶
(▶<.*║.*)(.)▶
$1▶$2
T`ÿ-`o`(?<=▶\+.*║.*▶).      # +
^\+

T`-ÿ`ÿo`(?<=▶-.*║.*▶).      # -
^-

(▶\..*├.*)(║.*▶)(.)         # .
$1$3$2$3
(▶,.*│)(.?)(.*├.*▶).        # ,
$1$3$2
▶\[(.*║.*▶)                 # [
[▶▶${1}
{`(▶▶+)([^[\]]*)\[
$2[$1▶
}`▶(▶+)([^[\]]*)\]
$2]$1
r`([[\]]*)▶\](.*║.*▶[^])    # ]
$1◀◀]$2
r{`\[([^[\]]*)(◀+)◀
$2[$1
}`\]([^[\]]*)(◀◀+)
$2◀]$1
◀
▶
}`▶([^│])(.*║)              # next instruction
$1▶$2
s\`.*├|║.*                  # print output

คลิกที่นี่เพื่อดูรหัสที่มีเลขศูนย์แทน null ไบต์ การเกิดขึ้นของใด ๆ ที่$0ไม่ควรแทนที่ด้วย nulls

แก้ไข : ตอนนี้สนับสนุนอินพุตว่างและหยุดการขึ้นบรรทัดใหม่

รองรับเอาต์พุตไม่สิ้นสุด (403 ไบต์)


ฉันหวังว่าฉันจะวาง<code>และ<tape>ถัดจากกันและกัน (แม้ว่ามันจะเป็นตัวละครมากขึ้น) ดังนั้นการเปลี่ยนไปใช้ล่าม SMBF จะง่ายขึ้นถ้าฉันตัดสินใจทำเช่นนั้น
mbomb007

14

TI-BASIC, 264 ไบต์

เนื่องจากข้อ จำกัด ใน TI-BASIC สิ่งนี้จึงไม่ผ่านเกณฑ์สำหรับความท้าทายนี้เนื่องจากแบ่งเป็น 2 แรมเครื่องคิดเลขจะถูก จำกัด มากและทำสิ่งที่ต้องการ30000->dim(L1(ผมใช้ L1 สำหรับกอง / อาร์เรย์) ERR:MEMORYจะบังคับให้มันโยน ดังนั้นสแต็ก / อาร์เรย์เริ่มต้นที่ขนาด 1 และเพิ่มขึ้นหากตัวชี้ชี้ไปที่องค์ประกอบผ่านจุดสิ้นสุดของมัน นอกจากนี้ยังแบ่งกฎ 3 เนื่องจากกฎข้อ 2 แตกแล้วดังนั้นฉันอาจไม่ต้องกังวลกับการ จำกัด ขนาดของเซลล์

อาจจะยังคงเป็นกอล์ฟโดยวิธี ... ฉันได้ทำการแก้ไขหนึ่งหรือสองถึงจุดสิ้นสุดตั้งแต่การส่งครั้งแรก แต่ถ้ารุ่นด้านล่างใช้งานไม่ได้แล้วกลับไปที่การแก้ไขตั้งแต่วันที่ 6 พฤษภาคม 15 และใช้สิ่งนั้น รหัสแทน นอกจากนี้เนื่องจากไม่มี ASCII จริง ๆ ใน TI-BASIC จึงใช้ตัวเลขขนาดใดก็ได้ (และสิ่งใดก็ตามที่ส่งกลับตัวเลขเช่นตัวแปรหรือนิพจน์) เป็นอินพุตและตัวเลขขาออก

ใช้SourceCoderเพื่อสร้างเป็นไฟล์. 8xp จากนั้นส่งไปยังเครื่องคิดเลขของคุณด้วย TI-Connect หรือ TILP หรือบางสิ่งและเรียกใช้โดยการรวมโปรแกรม brainfuck ของคุณในเครื่องหมายคำพูดคู่ตามด้วยเครื่องหมายจุดคู่และตามชื่อโปรแกรม TI-BASIC ตัวอย่างเช่นถ้าคุณตั้งชื่อมัน BRAINF "brainfuck goes here":prgmBRAINFคุณต้องการเรียกใช้โปรแกรมเช่นนี้: ถ้าคุณมีเปลือก Calc ของคุณที่ดักคำสั่งอื่น ๆ เมื่อตรวจพบที่prgmโทเค็น "brainfuck goes here" -> press ENTER -> prgmBRAINFแต่ทำเช่นนี้:

seq(inString("<>-+.,[]",sub(Ans,S,1)),S,1,length(Ans->L2
cumSum((Ans=7)-(Ans=8->L3
seq(Ans(X),X,dim(Ans),1,~1->L4
1->P:DelVar L11->dim(L1 //this is the same as DelVar L1:1->dim(L1 as DelVar does not require a colon or newline after its argument
For(S,1,dim(L2
L2(S->T
P-(T=1)+(T=2->P
dim(L1
Ans+(P-Ans)(P>Ans->dim(L1
L1(P)-(T=3)+(T=4->L1(P
If T=5
Disp Ans
If T=6:Then
Input V
V->L1(P
End
If T=7 and not(L1(P
S+2+sum(not(cumSum(L3(S)-1=seq(L3(X),X,S+1,dim(L3->S
1-S+dim(L3
If T=8 and L1(P
S-sum(not(cumSum(L4(Ans)=seq(L4(X),X,Ans+1,dim(L4->S
End

หากคุณไม่มีวิธีเชื่อมต่อเครื่องคิดเลขกับคอมพิวเตอร์ของคุณและต้องการพิมพ์ออกมาบนคอมพิวเตอร์แทน (ฉันไม่สามารถจินตนาการได้ว่าทำไมคุณต้องการ แต่ฉันพูดนอกเรื่อง) ทราบว่า->เป็นSTO>ปุ่มด้านบน คีย์~เป็นสัญลักษณ์เชิงลบถัดจาก ENTER และเพื่อแทนที่อินสแตนซ์ทั้งหมดL<number>ด้วยโทเค็นรายการที่เกี่ยวข้องที่พบ2ND -> <number on keypad>

ขอบคุณthomas-kwa (อย่างน้อยฉันคิดว่าเป็นชื่อผู้ใช้แบบสแต็กของเขา) ที่ช่วยฉันเพิ่มประสิทธิภาพนี้โดยเฉพาะกับคำแนะนำ[และ]


1
คุณต้องการผู้อุปถัมภ์รอบ ๆAns+Sไหม?
Zacharý

@ Zacharýจับได้ดีไม่ ฉันต้องไม่แน่ใจเกี่ยวกับวิธีการทำงานของ PEMDAS หรือบางสิ่งบางอย่าง ... ฉันจะละเว้นจากการแก้ไขอย่างไรก็ตามเพราะมันนานมากแล้วที่มันไม่คุ้มที่จะชนโพสต์นี้ไปทางด้านหน้าและเพราะสองไบต์ การลดจะไม่ให้คำตอบใด ๆ ที่เป็นประโยชน์มากกว่าคนอื่น ๆ ฮ่า ๆ
MI Wright

1
ฉันจำได้เมื่อ 2-3 ปีก่อนเมื่อฉันใช้โปรแกรมนี้เพื่อตีความ Brainf *** บนเครื่องคิดเลข และมันเป็นคำถามที่แปลความหมายของสมองฉันคิดว่ามันควรจะอยู่ที่จุดสูงสุดเพื่อความซื่อสัตย์
Zacharý

1
อันที่จริงฉันคิดว่าอาจเป็นS-sum(not(cumSum(L4(Ans)=seq(L4(X),X,Ans+1,dim(L4->Sไปได้ทั้งหมด ( a-a=0) และเฮ้ไม่ต้องกังวลเกี่ยวกับการลืมสิ่งหนึ่งของการดำเนินงานที่นี่ฉันได้เห็นโฮสต์ทั้งหมดของคนลืมคำสั่งของการดำเนินการสำหรับ%(mod) ในความท้าทาย
Zacharý

1
โอ้แดงใช่ โอเคที่ให้อย่างน้อย 10 ไบต์ตั้งแต่ถ้าสามารถทำซับเดียวรวมทั้งสิ่งอื่น ๆ ... อาจแก้ไขได้เช่นกัน คุณทำให้ฉันทำเครื่องคิดเลขเป็นครั้งแรกในรอบปีเพื่อตรวจสอบสิ่งนี้ฮ่า ๆ
MI Wright

13

Python 275 248 255

ฉันตัดสินใจที่จะลอง

import sys
i=0
b=[0]*30000
t=''
for e in open(sys.argv[1]).read():
 t+=' '*i+['i+=1','i-=1','b[i]+=1','b[i]-=1','sys.stdout.write(chr(b[i]))','b[i]=ord(sys.stdin.read(1))','while b[i]:','pass','']['><+-.,['.find(e)]+'\n'
 i+=(92-ord(e))*(e in'][')
exec t 

12
ไม่เรียบร้อยคุณกำลังสร้างซอร์สโค้ดโดยใช้ brainfuck

1
คุณสามารถดึง 1 ถ่าน "นำเข้า sys เป็น s" และแทนที่ "sys" เป็น "s" ในส่วนที่เหลือ
คุณ

โปรดทราบว่านี่เป็นจริง 247 ตัวอักษร (ดูพื้นที่ที่น่ารังเกียจหลังจากexec t?) หากคุณใช้เคล็ดลับของS.Markและทำให้ทั้งforวงจรเป็นหนึ่งบรรทัดคุณสามารถลดขนาดนี้เป็น 243 ตัวอักษร
Oleh Prypin

สิ่งนี้ล้มเหลวในอินพุตที่มีอยู่[]ซึ่งเป็นโปรแกรม bf ที่น่าสนใจ ฉันแนะนำให้แก้ไขซึ่งแก้ไขปัญหานี้ แต่เพิ่มจำนวนตัวอักษร เพื่อลดการนับจำนวนตัวอักษรที่คุณสามารถfrom sys import *และใช้แทน'i+=1,...'.split(',') ['i+=1',...]
บูธโดย

7
ฉันต้องการ+1แต่การปรับปรุงจำนวนมากได้รับการแนะนำและไม่ได้ดำเนินการ
mbomb007

12

Haskell, 457 413 ตัวอักษร

import IO
import System
z=return
'>'#(c,(l,d:r))=z(d,(c:l,r))
'<'#(d,(c:l,r))=z(c,(l,d:r))
'+'#(c,m)=z(succ c,m)
'-'#(c,m)=z(pred c,m)
'.'#t@(c,_)=putChar c>>hFlush stdout>>z t
','#(_,m)=getChar>>=(\c->z(c,m))
_#t=z t
_%t@('\0',_)=z t
i%t=i t>>=(i%)
b('[':r)=k$b r
b(']':r)=(z,r)
b(c:r)=f(c#)$b r
b[]=(z,[])
f j(i,r)=(\t->j t>>=i,r)
k(i,r)=f(i%)$b r
main=getArgs>>=readFile.head>>=($('\0',("",repeat '\0'))).fst.b

รหัสนี้ "คอมไพล์" โปรแกรม BF เป็นการIOกระทำของแบบฟอร์มState -> IO Stateสถานะคือ zipper บนสตริงที่ไม่สิ้นสุด

น่าเศร้าที่ฉันต้องจ่าย 29 ตัวอักษรเพื่อปิดบัฟเฟอร์ หากไม่มีสิ่งเหล่านี้แล้วก็ใช้งานได้ แต่คุณไม่เห็นข้อความแจ้งก่อนที่คุณจะต้องพิมพ์อินพุต คอมไพเลอร์เอง ( b, fและk) เพียง 99 ตัวอักษรรันไทม์ ( #และ%) คือ 216 คนขับ w / เริ่มต้นสถานะอื่น 32

>ghc -O3 --make BF.hs 
[1 of 1] Compiling Main             ( BF.hs, BF.o )
Linking BF ...

>./BF HELLO.BF 
Hello World!

>./BF PRIME.BF 
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 

ปรับปรุง 2011-02-15:ข้อเสนอแนะของ JB ได้รวมเปลี่ยนชื่อเล็กน้อยและทำให้รัดกุมขึ้นmain


1
คุณควรจะได้รับบัฟเฟอร์จาก just IOและอาร์กิวเมนต์จาก just System(-19) ปัญหาบัฟเฟอร์ทำให้ฉันรำคาญเช่นกันเนื่องจากสเป็คไม่ได้พูดถึงมันจริงๆและคำตอบที่ได้รับการโหวตสูงสุดไม่ได้ทำ I / O หากคุณต้องรักษามันอาจจะสั้นกว่าhFlushหลังจากเขียนแต่ละครั้งกว่าเปลี่ยนโหมดการบัฟเฟอร์ทั่วโลก (-34 + 15)
JB

11

สายพานลำเลียง 953

นี่อาจเป็นรหัสที่สวยที่สุดที่คุณเคยเห็น:

0

:I\1\@p
>#====)
^#====<
PP0
P<=======================<
00t:)01t1  a:P:P:P:P:P:P:^
>===========">">2>">2>">"^
^           +^-^5^ ^5^]^.^
^           "^"^*^"^*^"^"^
^           -^-^6^-^6^-^-^
^           #^#^*^#^*^#^#^
^           P P -^P )^P P
^           P P #^P )^P P
^t1\)t0:))t01   P   -^  1
^===========<   P   #^  0
^  t1\(t0:))t01     P   t
^=============<     P   )
^         t11(t01   0 0 )
^===============<. t P 10
^                 FT#T#=<
^=================< P 
^             t11)t01 
^===================< 10t))0tP00t:(01t(1a:P:
^                     >=====#=>==========">"
^                             ^          ]^[
^                           P ^          "^"
^===========================<=^#=====<   -^-
                            ^==<     ^ PP#^#=
                                     ^===PTPT<
                                     ^  )P P
                                     ^=<=< (
                                       ^===<

8
คุณสามารถเพิ่มคำอธิบายและลิงค์ไปยังการใช้งานได้หรือไม่? ฉันต้องการเข้าใจความงาม ;)
DLosc

1
ดีฉันกำลังพัฒนาก็มีความเป็นคอมไพเลอร์และคำอธิบายที่ดีมากที่github.com/loovjo/Conveyor แหล่งที่มานั้นค่อนข้างอ่านได้ถ้าคุณต้องการที่จะเข้าใจ
Loovjo

9

C 284 362 (จากไฟล์)

#include <stdio.h>
char b[30000],z[9999],*p=b,c,*a,i;f(char*r,int s){while(c=*a++){if(!s){(c-62)?(c-60)?(c-43)?(c-45)?(c-46)?(c-44)?0:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;if(c==91)f(a,!*p);else if(c==93){if(!*p)return;else a=r;}}else{if(c==93){--s;if(!*p&&!s)return;}else if(c==91){s++;}}}}main(int c,char**v){fread(z,1,9999,fopen(*++v,"r"));a=z;f(0,0);}

ช่วงเวลา:

ราคาสูงถึง: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
กดปุ่มใดก็ได้เพื่อดำเนินการต่อ . .

รวบรวมและวิ่งได้สำเร็จ VS2008

โซลูชันดั้งเดิมไม่รู้จักลูปที่ตั้งค่าเริ่มต้นเป็นศูนย์ ยังคงมีบางห้องที่จะเล่นกอล์ฟ แต่ในที่สุดก็แก้ปัญหาโปรแกรม Prime Number

Ungolfed:

#include <stdio.h>
char b[30000],z[9999],*p=b,c,*a,i;
f(char*r,int s)
{
    while(c=*a++)
    {   
        if(!s)
        {
            (c-62)?(c-60)?(c-43)?(c-45)?(c-46)?(c-44)?0:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;
            if(c==91)f(a,!*p);
            else if(c==93){if(!*p)return;else a=r;}
        }
        else
        {
            if(c==93)
            {
                --s;
                if(!*p&&!s)return;
            }
            else if(c==91)
            {
                s++;
            }
        }
    }
}

main(int c,char**v){
    fread(z,1,9999,fopen(*++v,"r"));
    a=z;
    f(0,0);
}

แบบทดสอบ:

สวัสดีชาวโลก

ROT13


คุณตรวจสอบตัวชี้เดียวกัน ( l) ทุกครั้งที่คุณวนซ้ำหรือไม่ ฉันคิดว่าคุณควรตรวจสอบตำแหน่งปัจจุบันของหัว ( p)
Alexandru

ฉันผ่านตัวชี้ไปที่บัฟเฟอร์และตัวชี้ไปยังกระแส มันจะตรวจสอบในตอนท้ายของวงเพื่อดูว่าตัวชี้ในบัฟเฟอร์ได้ถึงศูนย์และแบ่งอื่นมันรีเซ็ตกระแสกลับไปห่วงเดิมl [นี่เป็นสิ่งจำเป็นสำหรับ[ลูปซ้อนกัน
snmcdonald

1
ใช่. ฉันคิดอย่างนั้น คุณไม่ควรตรวจสอบค่าที่ตัวชี้ในตอนแรกป้อนในการวนรอบ แต่ค่าที่ตัวชี้ปัจจุบัน ตรวจสอบการทดสอบในคำถาม โปรแกรมของคุณค้าง
Alexandru

1
คุณสามารถแทนที่โดยbreak;else return;
Alexandru

3
ฉันคิดว่าคุณสามารถแทนที่ด้วย(c==62)?a:b (c-62)?b:a
Alexandru

9

PHP 5.4, 296 294 273 263 261 209 191 183 178 166 ตัวอักษร:

ฉันให้มันโดยไม่ใช้ eval แต่ในที่สุดฉันก็ต้องใช้มัน

<?$b=0;eval(strtr(`cat $argv[1]`,["]"=>'}',"["=>'while($$b){',"."=>'echo chr($$b);',","=>'$$b=fgetc(STDIN);',"+"=>'$$b++;',"-"=>'$$b--;',">"=>'$b++;',"<"=>'$b--;']));

คำสั่งทั้งหมดใช้งานได้ การทำเช่นนี้เป็นการละเมิดตัวแปรตัวแปรอย่างหนักและพ่นคำเตือน อย่างไรก็ตามหากมีใครเปลี่ยน php.ini ของพวกเขาเป็น squelch คำเตือน (หรือไปป์ stderr เป็น / dev / null) สิ่งนี้ใช้ได้ดี

การยืนยัน (เป็นตัวอย่างของ "Hello World!" จากWikipedia ): http://codepad.viper-7.com/O9lYjl

Ungolfed, 367 365 335 296 267 ตัวละคร:

<?php
$a[] = $b = 0;
$p = implode("",file($argv[1])); // Shorter than file_get_contents by one char
$m = array("]" => '}', "[" => 'while($a[$b]){',"." => 'echo chr($a[$b]);', "," => '$a[$b]=fgetc(STDIN);', "+" => '$a[$b]++;', "-" => '$a[$b]--;', ">" => '$b++;', "<" => '$b--;');
$p = strtr($p,$m);
@eval($p);

ควรรันผ่านบรรทัดคำสั่ง: php bf.php hello.bf


8

Windows PowerShell, 204

'$c=,0*3e4;'+@{62='$i++
';60='$i--
';43='$c[$i]++
';45='$c[$i]--
';44='$c[$i]=+[console]::ReadKey().keychar
';46='write-host -n([char]$c[$i])
';91='for(;$c[$i]){';93='}'}[[int[]][char[]]"$(gc $args)"]|iex

Invoke-Expressionแปลงตรงไปตรงมาเป็นธรรมของคำแนะนำแล้ว

ประวัติความเป็นมา:

  • 2011-02-13 22:24 (220) ความพยายามครั้งแรก
  • 2011/02/13 22:25 (218) จะสั้นกว่า3e430000
  • 2011-02-13 22:28 (216) การขึ้นบรรทัดใหม่ที่ไม่จำเป็น การจับคู่กับจำนวนเต็มแทนที่จะเป็นอักขระจะสั้นกว่า
  • 2011/02/13 22:34 (207) switchดัชนีมือสองในตารางแฮชแทน
  • 2011-02-13 22:40 (205) การร่ายสตริงให้ดีขึ้นจะเป็นการลบวงเล็บสองอันออก
  • 2011/02/13 22:42 (204) Write-Hostไม่ต้องใช้พื้นที่หลังจากอาร์กิวเมนต์

8

C, 333 ตัวอักษร

นี่คือล่าม BF คนแรกของฉันและเป็นครั้งแรกที่ฉันต้องตรวจแก้จุดบกพร่อง

สิ่งนี้จะรันตัวสร้างหมายเลขเฉพาะบน Mac OS X / GCC แต่#include<string.h>อาจจำเป็นต้องมีการเพิ่มเติมเพิ่มเติมในราคา 19 ตัวอักษรหากคำจำกัดความโดยนัยของstrchrไม่เกิดขึ้นกับแพลตฟอร์มอื่น O_RDONLY == 0นอกจากนี้ก็ถือว่า นอกเหนือจากนั้นการออกintจากการประกาศตัวMช่วย 3 ตัว แต่ดูเหมือนจะไม่เป็นไปตามมาตรฐาน C99 เช่นเดียวกันกับที่สามใน*b()

ขึ้นอยู่กับรายการของการเข้ารหัส ASCII ตัวดำเนินการ Brainfuck เป็นคู่เสริมทั้งหมดคั่นด้วยระยะทาง 2 ในพื้นที่รหัส ASCII แต่ละฟังก์ชันในโปรแกรมนี้ใช้ตัวดำเนินการหนึ่งคู่

#include<unistd.h>
char C[30000],*c=C,o,P[9000],*p=P,*S[9999],**s=S,*O="=,-\\",*t;
m(){c+=o;}
i(){*c-=o;}
w(){o<0?*c=getchar():putchar(*c);}
b(){if(o>0)*c?p=*s:*--s;else if(*c)*++s=p;else while(*p++!=93)*p==91&&b();}
int(*M[])()={m,i,w,b};
main(int N,char**V){
read(open(V[1],0),P,9e3);
while(o=*p++)
if(t=strchr(O,++o&~2))
o-=*t+1,
M[t-O]();
}

ฉันคิดว่าคุณสามารถหดมันได้มากขึ้นโดยใช้เครื่องหมาย 'e' สำหรับตัวเลขขนาดใหญ่ทั้งหมด
luser droog

@luser: ตอนแรกฉันก็รู้สึกประหลาดใจเหมือนกัน แต่ภาษาและคอมไพเลอร์ไม่อนุญาต ฉันจัดการเพื่อลดขนาดตัวอักษรอีก 4 ตัวที่มีการปรับแต่งและการใช้#defineตารางฟังก์ชั่นแทนก็อาจจะแย่ลง ฉันชอบหมายเลข 333 และโต๊ะ: v)
Potatoswatter

โอ้ใช่. ฉันควรจะรู้ว่าจริง ๆ แล้ว E- สัญกรณ์อยู่ในการผลิตสำหรับค่าคงที่จุดลอยตัวในขณะที่การประกาศต้องมีจำนวนเต็ม BTW นี่อาจเป็นการโกง แต่ลองดูnieko.net/projects/brainfuckสำหรับรุ่น Urban Müller ||กำไรที่ใหญ่ที่สุดดูเหมือนจะใช้งานหนักของ
luser droog

8

CJam, 75 ไบต์

lq3e4Vc*@{"-<[],.+>"#"T1$T=(t T(:T; { _T=}g \0+(@T@t _T=o "_'(')er+S/=}%s~@

ลองมันออนไลน์: สตริง reverser , Hello World

คำอธิบาย

รับรหัสในบรรทัดแรกของ STDIN และป้อนข้อมูลในทุกบรรทัดด้านล่าง

l            Read a line from STDIN (the program) and push it.
 q           Read the rest of STDIN (the input) and push it.
  3e4Vc*     Push a list of 30000 '\0' characters.
        @    Rotate the stack so the program is on top.

{               }%   Apply this to each character in prog:
 "-<[],.+>"#         Map '-' to 0, '<' to 1, ... and everything else to -1.
            ...=     Push a magical list and index from it.

s~       Concatenate the results and evaluate the resulting string as CJam code.
  @      Rotate the top three elements again -- but there are only two, so the
         program terminates.

แล้วรายการเวทมนต์นั้นล่ะ?

"T1$T=(t T(:T; { _T=}g \0+(@T@t _T=o "  Space-separated CJam snippets.
                                        (Note the final space! We want an empty
                                        string at the end of the list.)
_'(')er+                                Duplicate, change (s to )s, append.
        S/                              Split over spaces.

รายการผลลัพธ์มีดังนี้:

T1$T=(t    (-)
T(:T;      (<)
{          ([)
_T=}g      (])
\0+(@T@t   (,)
_T=o       (.)
T1$T=)t    (+)
T):T;      (>)
{          (unused)
_T=}g      (unused)
\0+(@T@t   (unused)
_T=o       (unused)
           (all other characters)

เราสร้างตัวอย่างสำหรับ+และ>จากนั้นสำหรับ-และ<เพียงแค่เปลี่ยน parens ด้านซ้าย ("การลดลง" ของ CJam) เป็น parens ที่ถูกต้อง ("การเพิ่มขึ้น" ของ CJam)


คำตอบที่สั้นที่สุด & ผู้ชนะที่ยิ่งใหญ่ที่สุด
Jack Giffin

7

F #: 489 ตัวอักษร

โปรแกรมต่อไปนี้ไม่ข้ามไปที่คำแนะนำ '[' / ']' แต่สแกนซอร์สโค้ดเพื่อหาโทเค็นที่ตรงกันถัดไป แน่นอนว่านี่ทำให้ช้า แต่ก็ยังสามารถหาช่วงเวลาที่ต่ำกว่า 100 ชนิด F # จำนวนเต็มไม่ล้น แต่ปิดล้อม

นี่เป็นเวอร์ชั่นย่อ:

[<EntryPoint>]
let M a=
 let A,B,i,p,w=Array.create 30000 0uy,[|yield!System.IO.File.ReadAllText a.[0]|],ref 0,ref 0,char>>printf"%c"
 let rec g n c f a b=if c then f i;if B.[!i]=a then g(n+1)c f a b elif B.[!i]=b then(if n>0 then g(n-1)c f a b)else g n c f a b
 while !i<B.Length do(let x=A.[!p]in match B.[!i]with|'>'->incr p|'<'->decr p|'+'->A.[!p]<-x+1uy|'-'->A.[!p]<-x-1uy|'.'->w x|','->A.[!p]<-byte<|stdin.Read()|'['->g 0(x=0uy)incr '['']'|']'->g 0(x>0uy)decr ']''['|_->());incr i
 0

gotcha ที่น่ารังเกียจก็คือโปรแกรม primes.bf ทำให้เกิดการขึ้นบรรทัดใหม่ของ Windows ในการใช้งานฉันต้องบันทึกหมายเลขอินพุตลงในเอกสารข้อความที่จัดรูปแบบ UNIX และป้อนไปยังโปรแกรมด้วยไพพ์:

interpret.exe prime.bf < number.txt

แก้ไข: ป้อน Alt + 010 ตามด้วย Enter จะทำงานใน Windows cmd.exe ด้วย

นี่คือรุ่นที่ยาวกว่า:

[<EntryPoint>]
let Main args =
    let memory = Array.create 30000 0uy
    let source = [| yield! System.IO.File.ReadAllText args.[0] |]
    let memoryPointer = ref 0
    let sourcePointer = ref 0
    let outputByte b = printf "%c" (char b)
    let rec scan numBraces mustScan adjustFunc pushToken popToken =
        if mustScan then
            adjustFunc sourcePointer
            if source.[!sourcePointer] = pushToken then
                scan (numBraces + 1) mustScan adjustFunc pushToken popToken
            elif source.[!sourcePointer] = popToken then
                if numBraces > 0 then scan (numBraces - 1) mustScan adjustFunc pushToken popToken
            else
                scan numBraces mustScan adjustFunc pushToken popToken 

    while !sourcePointer < source.Length do
        let currentValue = memory.[!memoryPointer]
        match source.[!sourcePointer] with
            | '>' -> incr memoryPointer
            | '<' -> decr memoryPointer
            | '+' -> memory.[!memoryPointer] <- currentValue + 1uy
            | '-' -> memory.[!memoryPointer] <- currentValue - 1uy
            | '.' -> outputByte currentValue
            | ',' -> memory.[!memoryPointer] <- byte <| stdin.Read()
            | '[' -> scan 0 (currentValue = 0uy) incr '[' ']'
            | ']' -> scan 0 (currentValue > 0uy) decr ']' '['
            |  _  -> ()
        incr sourcePointer
    0 

ฉันแก้ไขปัญหาการเข้าโดยไม่กด แต่ Ctrl + J :-)
Joey

Ctrl + J ไม่ทำงานสำหรับฉัน แต่ป้อน Alt + 010 ตามด้วย Enter ทำ
cfern

7

Delphi, 397 382 378 371 366 364 328 ตัวอักษร

กิน Delphi นี้!

328 var p,d:PByte;f:File;z:Word=30000;x:Int8;begin p:=AllocMem(z+z);d:=p+z;Assign(F,ParamStr(1));Reset(F,1);BlockRead(F,p^,z);repeat z:=1;x:=p^;case x-43of 1:Read(PChar(d)^);3:Write(Char(d^));0,2:d^:=d^+44-x;17,19:d:=d+x-61;48,50:if(d^=0)=(x=91)then repeat p:=p+92-x;z:=z+Ord(p^=x)-Ord(p^=x xor 6);until z=0;end;Inc(p)until x=0;end.

ที่นี่รหัสเดียวกันเยื้องและแสดงความคิดเห็น:

var
  d,p:PByte;
  x:Int8;
  f:File;
  z:Word=30000;
begin
  // Allocate 30000 bytes for the program and the same amount for the data :
  p:=AllocMem(z+z);
  d:=p+z;
  // Read the file (which path must be specified on the command line) :
  Assign(F,ParamStr(1));
  Reset(F,1);
  BlockRead(F,p^,z);
  // Handle all input, terminating at #0 (better than the spec requires) :
  repeat
    // Prevent a begin+end block by preparing beforehand (values are only usable in '[' and ']' cases) :
    z:=1;                       // Start stack at 1
    x:=p^;                      // Starting at '[' or ']'
    // Choose a handler for this token (the offset saves 1 character in later use) :
    case x-43of
      1:Read(PChar(d)^);        // ','     : Read 1 character from input into data-pointer
      3:Write(Char(d^));        // '.'     : Write 1 character from data-pointer to output
      0,2:d^:=d^+44-x;          // '+','-' : Increase or decrease data
      17,19:d:=d+x-61;          // '<','>' : Increase or decrease data pointer
      48,50:                    // '[',']' : Start or end program block, the most complex part :
        if(d^=0)=(x=91)then     // When (data = 0 and forward), or when (data <> 0 and backward)
        repeat                  //
          p:=p+92-x;            // Step program 1 byte back or forward
          z:=z+Ord(p^=x)        // Increase stack counter when at another bracket
              -Ord(p^=x xor 6); // Decrease stack counter when at the mirror char
        until z=0;              // Stop when stack reaches 0
    end;
    Inc(p)
  until x=0;
end.

อันนี้ใช้เวลาสองสามชั่วโมงกับฉันเพราะมันไม่ใช่โค้ดที่ปกติฉันเขียน แต่สนุก!

หมายเหตุ: การทดสอบสำคัญใช้งานได้ แต่ไม่หยุดที่ 100 เพราะอ่าน # 13 (CR) ก่อนหน้า # 10 (LF) ... การส่งอื่น ๆ ประสบปัญหานี้เช่นกันเมื่อทำงานบน CRLF OS หรือไม่


ว้าว! ฉันไม่เคยคาดหวังว่าจะกล้าหาญ C อย่างเด็ดขาดกับ Delphi! ไม่จนกว่าคุณจะใช้ความคิดของฉันกับ CI guess ;-)
PatrickvL

7

C, 260 + 23 = 283 ไบต์

ฉันสร้างโปรแกรม C ซึ่งสามารถพบได้ที่นี่

main(int a,char*s[]){int b[atoi(s[2])],*z=b,p;char*c=s[1],v,w;while(p=1,
*c){q('>',++z)q('<',--z)q('+',++*z)q('-',--*z)q('.',putchar(*z))q(',',*z
=getchar())if(*c=='['||*c==']'){v=*c,w=184-v;if(v<w?*z==0:*z!=0)while(p)
v<w?c++:c--,p+=*c==v?1:*c==w?-1:0;}c++;}}

จะต้องมีการรวบรวมผ่านgcc -D"q(a,b)"="*c-a||(b);" -o pmmbf pmmbf.cและสามารถเรียกได้ดังต่อไปนี้: pmmbf ",[.-]" 30000โดยอาร์กิวเมนต์แรก (ที่ยกมา) มีโปรแกรม bf-program ที่จะทำงานที่สองกำหนดขนาดของเทปที่ควรจะเป็น


1
ฉันคิดว่าคุณต้องเพิ่ม 23 ตัวอักษรในการนับของคุณสำหรับ-D"q(a,b)"="*c-a||(b);"ตัวเลือกเนื่องจากดูเหมือนว่า (อย่างน้อยความเข้าใจที่ จำกัด ของฉัน) เพื่อช่วยให้คุณลดขนาดรหัสของคุณ
Gareth

ตัวเลือกจะรวมอยู่ในข้อความที่โพสต์ เหตุผลก็คือเพื่อหลีกเลี่ยงคำที่ยาวdefineและขึ้นบรรทัดใหม่ แต่ฉันไม่คิดว่ามันเพียวจริง ๆ อย่างไรก็ตามด้วยคำพูดแสดงความคิดเห็นและgcc -Dฉันไม่เห็นประโยชน์เลย
Potatoswatter

5

C, 267

#define J break;case
char*p,a[40000],*q=a;w(n){for(;*q-93;q++){if(n)switch(*q){J'>':++p;J'<':--p;J'+':++*p;J'-':--*p;J'.':putchar(*p);J',':*p=getchar();}if(*q==91){char*r=*p&&n?q-1:0;q++;w(r);q=r?r:q;}}}main(int n,char**v){p=a+read(open(v[1],0),a,9999);*p++=93;w(1);}

ทำงานเป็น. /a.out primes.bf

เวอร์ชันที่ไม่ถูกปรับแต่ง:

#define J break;case

char*p,a[40000],*q=a; // packed so program immediately followed by data

w(n){
    for(;*q-93;q++){ // until ']'
        if(n)switch(*q){ // n = flagged whether loop evaluate or skip(0)
                J'>':++p;
                J'<':--p;
                J'+':++*p;
                J'-':--*p;
                J'.':putchar(*p);
                J',':*p=getchar();
        }
        if(*q==91){char*r=*p&&n?q-1:0;q++;w(r);q=r?r:q;} // recurse on '[', record loop start
    }
}

main(int n,char**v){
    p=a+read(open(v[1],0),a,9999);
    *p++=93; // mark EOF with extra ']' and set data pointer to next
    w(1); // begin as a loop evaluate
}

5

Python 2, 223

ฉันยอมรับว่าฉันรีไซเคิลโปรแกรมเก่าของฉัน (แต่ต้องเปลี่ยนมันสักหน่อยเพราะเวอร์ชั่นเก่าไม่มีข้อมูล แต่การตรวจสอบข้อผิดพลาด ... )

P="";i,a=0,[0]*30000
import os,sys
for c in open(sys.argv[1]).read():x="><+-.[,]".find(c);P+=" "*i+"i+=1 i-=1 a[i]+=1 a[i]-=1 os.write(1,chr(a[i])) while+a[i]: a[i]=ord(os.read(0,1)) 0".split()[x]+"\n";i+=(x>4)*(6-x)
exec P

รันเครื่องคิดเลขเฉพาะช่วงเวลาได้ดี

ฉันเห็นแล้วว่า Alexandru มีคำตอบที่มีความคล้ายคลึงกันบ้าง ฉันจะโพสต์คำตอบ mny ต่อไปเพราะฉันคิดว่ามีความคิดใหม่ ๆ อยู่ในนั้น


5

C (gcc) Linux x86_64, 884 621 525 487 439 383 358 354 ไบต์

*z,*mmap();d[7500];(*p)();*j(a,g)char*a;{char*t=a,*n,c,q=0;for(;read(g,&c,!q);)t=c==91?n=j(t+9,g),z=mempcpy(t,L"\xf003e80Ƅ",5),*z=n-t-9,n:c==93?q=*t++=233,z=t,*z=a-13-t,z+1:stpcpy(t,c-62?c-60?c-43?c-45?c-46?c-44?"":"1\xc0P_\xF\5":"RXR_\xF\5":L"໾":L"۾":L"컿":L"웿");return t;}main(P,g)int**g;{p=mmap(0,1<<20,6,34,0,0);p(*j(p,open(g[1],0))=195,d,1);}

ลองออนไลน์!

นี่คือ JIT ที่รวบรวมรหัส BF เป็นภาษาเครื่อง x86_64 ตอนรันไทม์ นี้จะดำเนินการแปลตรงดังนั้นโดยทั่วไปที่เกิดขึ้นวนเวียนเช่น>>>, <<<, +++และ---ยังไม่ได้รวมตัวกันเข้าไปในคำแนะนำได้เร็วขึ้น

รุ่น golfed น้อยกว่า:

// size of data area
*z,c,*mmap();d[7500];(*p)();
// recursive function translates BF commands to x86_64 instructions
*j(a,g)char*a;{
  char*t=a,*n,q=0;
  for(;read(g,&c,!q);)
    t=c==91? // [
        // cmpb $0x0,(%rsi)
        // je n-t-9
        n=j(t+9,g),
        z=mempcpy(t,L"\xf003e80Ƅ",5)
        *z=n-t-9,
        n
      :
        c==93? // ]
          // jmp a-13-t
          q=*t++=233,
          z=t,
          *z=a-13-t,
          z+1
        :
          stpcpy(t,c-62? // >
                     c-60? // <
                       c-43? // +
                         c-45? // -
                           c-46? // .
                             c-44? // ,
                               ""
                             :
                               // xor %eax,%eax
                               // push %rax
                               // pop %rdi
                               // syscall
                               "1\xc0P_\xF\5"
                           :
                             // push %rdx
                             // pop %rax
                             // push %rdx
                             // pop %rdi
                             // syscall
                             "RXR_\xF\5"
                         :
                           // decb (%rsi)
                           L"໾"
                       :
                         // incb (%rsi)
                         L"۾"
                     :
                       // dec %esi
                       L"컿"
                   :
                     // inc %esi
                     L"웿");
  return t;
}
main(P,g)int**g;{
  // allocate text (executable) memory and mark as executable
  p=mmap(0,1<<20,6,34,0,0);
  // run JIT, set %rdx=1 and call code like a function
  p(*j(p,open(g[1],0))=195,d,1);
}

4

C, 374 368

อ่านจากไฟล์ ผ่านการทดสอบ PRIME.BF

การใช้งาน: ./a.out PRIME.BF

#include <stdio.h>
main(int c,char**v){int m[30000],s[99],p=0,i=0,n=0;char l[9999],d;FILE*f=fopen(v[1],"r");for(l[i]=0;i<9999&&l[i]!=EOF;l[i]=getc(f))i++;for(i=1;d=l[i];i++){if(!n){p+=d-62?0:1;p-=d-60?0:1;m[p]+=d-43?0:1;m[p]-=d-45?0:1;if(d==46)putchar(m[p]);if(d==44){m[p]=getchar();}if(d==93){i=s[c]-1;c--;n++;}}if(d==91){if(m[p]){c++;s[c]=i;}else{n++;}}n-=d-93?0:1;}}


จัดรูปแบบ:

#include <stdio.h>
main(int c,char**v){
    int m[3000],s[99],p=0,i=0,n=0;
    char l[9999],d;
    FILE*f=fopen(v[1],"r");
    for(l[i]=0;i<9999&&l[i]!=EOF;l[i]=getc(f))i++;
    for(i=1;d=l[i];i++){
        if(!n){ // > < + - . , ] \n [ ]
            p+=d-62?0:1;
            p-=d-60?0:1;
            m[p]+=d-43?0:1;
            m[p]-=d-45?0:1;
            if(d==46)putchar(m[p]);
            if(d==44){m[p]=getchar();}
            if(d==93){i=s[c]-1;c--;n++;}
        }
        if(d==91){if(m[p]){c++;s[c]=i;}else{n++;}}
        n-=d-93?0:1;
    }
}

3000 vs 30000 บัฟเฟอร์ของคุณเล็กเกินไป ขนาดโปรแกรมเล็กเกินไป
Alexandru

ฉันพิมพ์ผิดคงที่ ขนาดโปรแกรมหมายถึงอะไร? หากคุณหมายถึงขนาดไฟล์สูงสุดคุณไม่ได้ระบุขั้นต่ำที่ควรจัดการ
jtjacques

4

ลัวะ 285

loadstring("m,p={0},1 "..io.open(arg[1]):read"*a":gsub("[^.,<>[%]+-]",""):gsub(".",{["."]="io.write(string.char(@)) ",[","]="@=io.read(1):byte() ",["<"]="p=p-1 ",[">"]="p=p+1 @=@or 0 ",["["]="while @~=0 do ",["]"]="end ",["+"]="@=(@+1)%256 ",["-"]="@=(@-1)%256 "}):gsub("@","m[p]"))()

รุ่นที่สามารถอ่านได้ค่อนข้าง:

loadstring( --execute
    "m,p={0},1 ".. --initialize memory and pointer
    io.open(arg[1]) --open file
        :read"*a" --read all
            :gsub("[^.,<>[%]+-]","") --strip non-brainfuck
                :gsub(".", --for each character left
                    {["."]="io.write(string.char(@)) ", -- '@' is shortcut for 'm[p]', see below
                    [","]="@=io.read(1):byte() ",
                    ["<"]="p=p-1 ",
                    [">"]="p=p+1 @=@or 0 ", --if a before unexplored memory cell, set to 0
                    ["["]="while @~=0 do ",
                    ["]"]="end ",
                    ["+"]="@=(@+1)%256 ", --i like it overflowing
                    ["-"]="@=(@-1)%256 "
                    }
                )
                    :gsub("@","m[p]") --replace the '@' shortcut
    ) --loadstring returns a function
() --call it

ทำงานได้อย่างสมบูรณ์แบบ

Lua, 478, ไม่มีโหลดสตริง

local m,p,i,r,c={0},1,1,{},io.open(arg[1]):read"*a"while i<=#c do(({[43]=function()m[p]=(m[p]+1)%256 end,[45]=function()m[p]=(m[p]-1)%256 end,[62]=function()p=p+1 m[p]=m[p]or 0 end,[60]=function()p=p-1 end,[46]=function()io.write(string.char(m[p]))end,[44]=function()m[p]=io.read(1):byte()end,[91]=function()if m[p]==0 then i=select(2,c:find("%b[]",i))else r[#r+1]=i end end,[93]=function()if m[p]==0 then r[#r]=nil else i=r[#r] end end})[c:byte(i)]or function()end)()i=i+1 end

รุ่นที่อ่านได้:

local m,   p, i, r,  c= --memory, pointer, brackets stack, code
      {0}, 1, 1, {}, io.open(arg[1]) --open file
              :read"*a" --read it
while i<=#c do --while there's code
    (
        (
            {
                [43]=function() -- +
                    m[p]=(m[p]+1)%256
                end,
                [45]=function() -- -
                    m[p]=(m[p]-1)%256
                end,
                [62]=function() -- >
                    p=p+1 m[p]=m[p]or 0 --if new memory cell, set it to 0
                end,
                [60]=function() -- <
                    p=p-1
                end,
                [46]=function() -- .
                    io.write(string.char(m[p]))
                end,
                [44]=function() -- ,
                    m[p]=io.read(1):byte()
                end,
                [91]=function() -- [
                    if m[p]==0 then
                        i=select(2,c:find("%b[]",i)) --find matching ]
                    else
                        r[#r+1]=i --push position to the stack
                    end
                end,
                [93]=function() -- ]
                    if m[p]==0 then
                        r[#r]=nil --pop from stack
                    else
                        i=r[#r] --go to position on the top of stack
                    end
                end
            }
        )[c:byte(i)] --transform character into code
        or function()end --do nothing on non-brainfuck
    )() --run the resulting function
    i=i+1 --go to the next opcode
end

4

Brainfuck, 948 ไบต์

นั่นใช้เวลาสักครู่ ฉันเล่นกอล์ฟล่ามตัวเองด้วย Brainfuck โดย ... ไม่ใช่ฉัน

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

4

เรียกคืน 594 ไบต์

กล่าวโดยย่อ: การเรียกคืนไม่มีตัวดำเนินการทางคณิตศาสตร์ในแง่คลาสสิคมันมีการใช้งานระดับบิตเท่านั้น คุณไม่สามารถเพียงแค่ "เพิ่มหนึ่ง" เป็นต้นการเรียกคืนเป็นไปตามสแต็กอย่างเคร่งครัด

DC505M22022M32032M606M42042M707M92092M4405022o032o06o042o07o092o044o1305022o06o042o092o52052q.q2305022o06o07o93093q.q5403206o07o14014q.q6403206o042o07o24024q.q74Yx34034z03MMMMMMMM034o3yY030401r3.4.101zyY040301r4.3.101zY01052gZ02Z040301052023s4.3.10zyY01023gZ02z030401023052s3.4.10zyY01093gZ02q20zyY01054gZ02u20zyY01014gZx20zyY01064gZ02X0zyY01024gZ03304302r33.43.20zyY01074gZ04303302r43.33.20zyyQ6205.8Y06208g6206208iZ08M808013izy062U7205.9Y07209g7207209iz09M909013izy072R53.63.82063MMMMMMMM053o63082013i53082KKKKKKKK82053063082S84.94.12.73.83t012073083TY083073012r83.73.12012084gzY012094gZt0zyy

ตัวอย่างที่ 1: พิมพ์บางสิ่งบางอย่าง

การป้อนข้อมูล:

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

เอาท์พุท:

PPCG rocks!

ตัวอย่างที่ 2: ส่งออกหมายเลขสแควร์สูงสุด 100

การป้อนข้อมูล:

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

เอาท์พุท:

0
1
4
9
16
25
36
49
64
81
100

ตัวอย่างนี้อาจใช้เวลาสักครู่ในการดำเนินการและอาจทำให้เกิดข้อความ "แท็บนี้ค้าง" ไม่ต้องสนใจและรอ


4
โดเมนเว็บไซต์ของคุณหมดอายุแล้ว นอกจากนี้คำตอบนี้ไม่ใช่การแข่งขันเนื่องจากภาษาใหม่กว่าความท้าทาย
mbomb007

3

OCaml (lex) 497 ตัวอักษร

OCamllex เป็นส่วนหนึ่งของการกระจายมาตรฐานของ OCaml

{let a=Array.create 30000 0
let(%)f g h=f(g h)
let s v i=a.(i)<-v;i
let o d i=s(a.(i)+d)i
let p i=print_char(Char.chr a.(i));flush stdout;i
let r i=s(Char.code(input_char stdin))i
let rec w g i=if 0=a.(i)then i else w g(g i)
let n x=x}
rule t f=parse
|'>'{t(succ%f)lexbuf}
|'<'{t(pred%f)lexbuf}
|'+'{t((o 1)%f)lexbuf}
|'-'{t((o(-1))%f)lexbuf}
|'.'{t(p%f)lexbuf}
|','{t(r%f)lexbuf}
|'['{t((w(t n lexbuf))%f)lexbuf}
|']'|eof{f}
|_{t f lexbuf}
{let _=t n(Lexing.from_channel(open_in Sys.argv.(1)))0}

บันทึกเป็น b.mll และเรียกใช้ด้วย

ocamllex b.mll && ocaml b.ml prime.bf

ฉันไม่ชอบการแยกวิเคราะห์ด้วยมือดังนั้นฉันจึงใช้เครื่องกำเนิด lexer ที่จัดไว้ให้ จากโทเค็นที่อ่านเราเขียนฟังก์ชันสำหรับโปรแกรม brainf * ck ทั้งหมด


3

C # (2861 ถ่าน, ~ 84 บรรทัด)

นี่ไม่ใช่วิธีแก้ปัญหาที่สวยที่สุดและอาจไม่ใช่ทั้งหมดของ 'Golf-ish' เนื่องจากฉันไม่ได้กังวลเรื่องความยาวอย่างที่ควรจะเป็น (ฉันไม่ได้ลบความคิดเห็นหรือพื้นที่สีขาวเพิ่มเติม) ฉันแค่อยากจะลองใช้ภาษาใหม่เพื่อดูว่าฉันสามารถทำได้หรือไม่ ถ้าฉันทำมันอีกครั้งฉันจะทิ้งการใช้สแต็คเพื่อกลับจาก ']' แล้วมองย้อนกลับไป รันโดยไม่มีอาร์กิวเมนต์บรรทัดคำสั่งรันโปรแกรม hello world ที่กำหนดไว้ในคำอธิบายปัญหา มันยอมรับอาร์กิวเมนต์บรรทัดคำสั่งหนึ่งชื่อไฟล์ของโปรแกรมที่จะเรียกใช้

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            String ProgSource;
            if (args.Length > 0)
                ProgSource = System.IO.File.ReadAllText(args[0]);
            else //hello world
                ProgSource = "";

            Stack<int> stack = new Stack<int>();
            char[] bfProg = ProgSource.ToCharArray();
            char[] mem = new char[30000];
            int ptr = 0;

            for (int ip = 0; ip<bfProg.Length; ip++){
                switch (bfProg[ip])
                {
                    case ('>'): ptr++;  break;
                    case ('<'): ptr--;  break;
                    case ('+'): mem[ptr]++; break;
                    case ('-'): mem[ptr]--; break;
                    case ('.'): Console.Write(mem[ptr]); break;
                    case (','): 
                        char key = Console.ReadKey(false).KeyChar;
                        if (key == '\r')
                        {
                            key = (char)10;
                            Console.WriteLine();
                        }
                        mem[ptr] = key;
                        break;
                    case ('['):
                        if (mem[ptr] == 0)
                        {
                            int openBraces = 1;
                            //find the closing brace for this expression
                            for (int x = 1; x < (bfProg.Length - ip); x++)
                            {
                                if (bfProg[ip + x] == ']') openBraces--;
                                if (bfProg[ip + x] == '[') openBraces++;
                                if (openBraces == 0)
                                {
                                    if (stack.Peek() == ip) stack.Pop();
                                    ip += x;
                                    break;
                                }                                
                            }
                       }
                       else
                       {
                           stack.Push(ip);
                       }
                       break;
                    case (']'):
                        if (mem[ptr] == 0)
                            stack.Pop();
                        else
                        {
                            ip = stack.Peek();
                        }
                        break;
                }
            }

            Console.WriteLine("\n\n\nExecution Completed Sucessfully. Press any key to continue...");
            Console.ReadKey();

        }
    }

}

แก้ไข: ลบการอ้างอิงที่ไม่ได้ใช้ออก


1
@ mbomb007 - อัปเดต ลืมไปเลยว่าฉันทำไป (ไม่รู้ตัวเลยว่ามีใครแม้แต่อ่านคำถามเก่า ๆ เหล่านี้)
TheB

ผู้คนยังอ่านพวกเขาไม่เพียง แต่พวกเขายังตอบและเล่นกอล์ฟ
mbomb007

3

C (gcc) , 273 268 ไบต์

main(_,a){_=fopen("w.c","w");fputs("main(){char a[30000],*p=a;",_);x:a=getchar();fputs(a-62?a-60?a-43?a-45?a-46?a-44?a-91?a-93?~a?"":"}":"}":"while(*p){":"*p=getchar();":"putchar(*p);":"--*p;":"++*p;":"--p;":"++p;",_);if(~a)goto x;fclose(_);system("cc w.c;./a.out");};

ลองออนไลน์!

-5 ต้องขอบคุณ catcat

รับอินพุตจาก stdin

สิ่งนี้อาศัยสภาพแวดล้อมเพียงเล็กน้อย แต่ค่อนข้างสอดคล้องกัน นี่เป็นวิธีแก้ปัญหา eval อย่างมีประสิทธิภาพสำหรับ c มันเขียนโปรแกรม C ที่เหมาะสมไปยังไฟล์ wc รวบรวมและเรียกใช้เป็นปฏิบัติการที่ต้องการ ดังนั้นในฐานะโบนัสเอฟเฟกต์นี้จะรวบรวมรหัส bf และทิ้งa.outเป็นไบนารี่ของมัน โปรดทราบว่าขึ้นอยู่กับระบบที่คุณอาจต้องแก้ไขสตริงสุดท้าย โดยเฉพาะคอมไพเลอร์ windows c ส่วนใหญ่จะเรียกใช้ "a.exe" ซึ่งเป็นค่าเริ่มต้น โชคดีเท่าที่ฉันสามารถบอกได้พวกเขาทั้งหมดมีความยาวเท่ากันดังนั้น bytecount ก็เหมือนกัน (แม้ว่าคุณจะยังไม่ได้กำหนดซีซีคุณอาจจำเป็นต้องเพิ่มตัวอักษรเช่น gcc ในคำสั่งคอมไพล์โดยเพิ่ม 1 ไบต์)

ฉันรู้ว่าเธรดนี้ค่อนข้างเก่า แต่ฉันยังไม่เห็นวิธีการแก้ปัญหาแบบ C นี้ดังนั้นฉันคิดว่าฉันจะเพิ่มมัน



2

[แก้ไข]

C ++ 11, 355 อ่านจากไฟล์:

#include<functional>
#include<stdio.h>
main(){
char b[30000],g[9999],*f=g,*p=b,n[]="+-,.><[]",j;
std::function<void()>m[]={
[&p]{(*p)++;},
[&p]{(*p)--;},
[&p]{*p=getchar();},
[&p]{putchar(*p);},
[&p]{p++;},
[&p]{p--;},
[&p,&f]{if(!(*p))while(*f-93)f++;},
[&f,&m]{while(*f-91)f--;m[6]();}
};
fread(g,1,9999,fopen(a[1],0));
for(;*f;f++)for(j=0;n[j];j++)if(n[j]==*f)m[j]();
}

ทดสอบ

http://ideone.com/b7vO4

[เวอร์ชั่นเก่า]

C ++ 11, 391 เพื่อดูการทำงาน: http://ideone.com/yZHVv

#include<functional>
#include<stdio.h>
main(int c,char **a) {
  char b[30000],g[9999],*f=g,*r=f,*p=b;
  std::function<void()>m[256];
  m['>']=[&p]{p++;};  
  m['<']=[&p]{p--;};
  m['+']=[&p]{(*p)++;};
  m['-']=[&p]{(*p)--;};
  m['.']=[p]{putchar(*p);};
  m[',']=[&p]{*p=getchar();};
  m['[']=[p,&r,&f]{*p?r=f-1:r=0;};
  m[']']=[&r,&f]{r?f=r:r=f;};
  fread(g,1,9999,fopen(a[1],"r"));
  while (c=*(f++))if(m[c]&&(r||c==']'))m[c]();
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.