Menafsirkan brainf ***


113

Tulis program terpendek dalam bahasa favorit Anda untuk menafsirkan program brainfuck . Program ini dibaca dari file. Input dan output adalah input standar dan output standar.

  1. Ukuran sel: 8bit tidak ditandatangani. Overflow tidak terdefinisi.
  2. Ukuran array: 30000 byte (tidak dilingkari)
  3. Perintah yang salah bukan bagian dari input
  4. Komentar dimulai dengan # dan berlanjut hingga akhir baris. Komentar adalah segalanya tidak masuk+-.,[]<>
  5. tidak ada simbol EOF

Tes yang sangat bagus dapat ditemukan di sini . Bunyinya nomor dan kemudian cetak nomor prima hingga nomor itu. Untuk mencegah pembusukan tautan, berikut adalah salinan kode:

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

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

Contoh dijalankan:

$ 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
Anda harus mengklarifikasi tentang 1) ukuran memori 2) apakah memori dilingkari 4) mungkin detail
Nakilon

3
Saya bertanya-tanya apakah harus ada dua kategori: Program-program yang menggunakan eval (atau keluar untuk mengkompilasi) - dan yang tidak.
MtnViewMark

34
Saya ingin melihat seseorang menjawab ini di brainfuck.
Hannesh

3
Apa yang dimaksud dengan "tanpa simbol EOF"? Bahwa nilai sel tetap tidak berubah ketika mencoba ,EOF? Atau terserah pada kita untuk memilih nilai saat mencoba ,EOF? Atau apakah EOF tidak terdefinisi secara keseluruhan?
Martin Ender

3
Demikian juga, apa yang harus terjadi ketika seseorang mencoba untuk meninggalkan sel 30k di kedua sisi? Haruskah kepala kaset tetap di tempatnya atau apakah ini perilaku yang tidak terdefinisi?
Martin Ender

Jawaban:


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

Ini menjalankan hello.bf dan primes.bf dengan sempurna:

$ 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

Inisialisasi: Tabel terjemahan opcode ke Perl disimpan di %c. Bentuk yang dapat dibaca terlihat seperti ini:

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

Langkah 1: Menghirup input program ke $_dan mengubahnya menjadi kode Perl menggunakan tabel terjemahan. Komentar dihapus secara otomatis (diganti denganundef ) pada langkah ini.

Langkah 2: Buka kompresi semua $b[$p] kejadian

Langkah 3: Luncurkan program menggunakan eval.


Cukup gunakan qwsintaks Perl untuk mendefinisikan %csecara langsung - baik untuk 7 karakter yang lebih sedikit (Anda harus mengatakan print+chr$b[$p]dan ord(getc), meskipun)
mob

Saya menghitung 18 disimpan ... terima kasih! (Pembaruan dalam satu menit)
JB

1
@olivecoder Apa yang kamu bicarakan?
JB

Tabel% c dideklarasikan dan didefinisikan pada baris pertama; karakternya dicatat dengan sempurna.
JB

@JB hei, saya tidak sengaja menekan suara pada jawaban Anda dan terkunci di dalam, bisakah Anda mengedit ini sehingga saya dapat membalikkan Vote ke bawah?
Sikloheksanol.

67

Python (tanpa eval), 317 byte

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 untukf(u,c,k)
Joel Cornett

9
Itu adalah suara yang sangat indah, tuan
globby

-1 byte jika Anda ganti while b*c[c[0]]and j<1denganwhile b*c[c[0]]*(j<1)
Daniil Tutubalin

50

16 bit 8086 kode mesin: 168 byte

Inilah versi yang disandikan base64 , konversi dan simpan sebagai 'bf.com' dan jalankan dari prompt perintah Windows: 'bf progname'

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

SUNTING

Inilah beberapa assembler (gaya A86) untuk membuat executable (saya harus merekayasa balik ini karena saya salah menempatkan sumber aslinya!)

    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

Saya telah menambahkan versi kode sumber program. Saya baru saja memperhatikan bahwa karakter non-bf menyebabkan program keluar daripada diabaikan. Mudah untuk memperbaikinya dan saya akan membiarkannya sebagai latihan bagi orang untuk melakukannya sendiri.
Skizz

Saya ingat saya mendapatkan versi Linux ELF 166 byte, 10 tahun yang lalu, di sini muppetlabs.com/~breadbox/software/tiny
Emmanuel

39

brainfuck , 843 691 byte

Sunting: memutuskan untuk mengunjungi kembali ini dan menemukan sejumlah cara mengejutkan untuk bermain golf dari byte

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

Ini mengambil input dalam bentuk di code!inputmana !inputopsional. Ini juga mensimulasikan sel negatif tanpa menggunakan sel negatif itu sendiri dan dapat menyimpan hingga (30000-(length of code+6))/2sel.

Cobalah online!


Hanya untuk memastikan saya mendapatkan ini dengan benar, jika saya menjalankan program ini dengan program ini saya bisa membuat sarangnya 5 level dan masih menangani kode-input dengan panjang 262.
Draco18s

@ Draco18s Saya menduga Anda akan kehabisan sel 30000 sebelum itu, karena ukuran masing-masing penerjemah bersarang meningkat secara eksponensial. Saya pikir Anda akan mendapatkan 2, mungkin 3 level
Jo King

Bahkan 3 kedalaman akan sangat konyol.
Draco18s

27

Ruby 1.8.7, 188 185 149 147 karakter

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]}*";"

Versi yang bisa dibaca:

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

Seperti yang Anda lihat, saya tanpa malu-malu mencuri ide Anda untuk menerjemahkan ke bahasa host dan kemudian menggunakan eval untuk menjalankannya.


Anda dapat mencukur habis byte byte dibandingkan dengan nol >0daripada menguji kesetaraan: !=0. Spesifikasi mengatakan tidak ditandatangani, dan overflow tidak ditentukan.
pengecut anonim

3e4juga akan berfungsi sebagai lawan30000
pengecut anonim

@Charlie: Terima kasih. Meskipun jujur, itu tidak mengatakan "unsigned" ketika saya menulis kode. Jujur saya tidak tahu bahwa Anda bisa menulis 3E4. Itu poin yang sangat bagus dan bagus untuk diketahui.
sepp2k

File.read($*.pop).bytes-> $<.bytesharus bekerja juga
Arnaud Le Blanc

1
Ruby 1.8.7 memiliki sintaks yang lebih pendek untuk membangun hash literal:, {?a,"foo"}yang setara dengan {?a=>"foo"}. Dan pengujian di sini menunjukkan bahwa Anda benar-benar dapat mengganti File.read($*.pop).bytesdengan $<tanpa masalah. Juga inlining semuanya menjadi sesuatu seperti eval"a[0]..."+$<.bytes.map{?.,"putc a[i]",...}*";"mempersingkat solusi dengan beberapa karakter lainnya.
Ventero

26

Binary Lambda Calculus 112

Program ditunjukkan dalam hex dump di bawah ini

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

mengharapkan inputnya terdiri dari program Brainfuck (hanya melihat bit 0,1,4 untuk membedakan antara, -. + <>] [) diikuti oleh a], diikuti oleh input untuk program Brainfuck.

Simpan hex dump di atas dengan xxd -r> bf.Blc

Dapatkan juru bahasa blc dari 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

Halo Dunia!


1
Mengapa ini ada? Ternyata, itu bahkan ada di ranah penelitian . Oo
Isiah Meadows

Jadi ini tidak akan bekerja dengan program brainfuck yang dikomentari?
kamoroso94

Tidak, bukan tanpa menghilangkan komentar terlebih dahulu.
John Tromp

18

Retina 0.8.2 , 386 391 386 byte

Kode berisi 0x00karakter NUL ( ) yang tidak dapat dicetak. Ini juga belum super golf, karena sudah sangat lambat, dan jika saya golf lagi, saya tidak tahu berapa lama untuk menyelesaikannya. Muncul waktu habis pada sampel temuan utama.

Mungkin ada bug di interpreter online atau di program saya (memimpin baris baru tidak muncul di output?).

Mengambil input seperti <code>│<input>. Tidak, itu bukan pipa ( |). Ini karakter Unicode U+2502. Kode ini juga menggunakan karakter Unicode ÿ▶◀├║. Karakter Unicode digunakan untuk mendukung input semua karakter ASCII. Oleh karena itu, karakter ini harus dipisahkan dari kode oleh karakter non-ASCII.

Cobalah online

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\`.*├|║.*

Perhatikan ada baris baru di sana.

Penjelasan singkat:

Nol 0x00digunakan untuk rekaman itu, yang tidak terbatas. Penggantian pertama mengatur interpreter dalam bentuk ▶<code>│<input>├<output>║▶<tape>, di mana yang pertama adalah penunjuk untuk kode, dan yang kedua adalah penunjuk untuk kaset.

ÿadalah 0xFF(255), yang digunakan untuk Transliterasi (digunakan untuk mengimplementasikan +dan -) untuk membungkus sel kembali menjadi nol.

hanya digunakan untuk keterbacaan (jika program dihentikan di tengah atau Anda ingin melihat program sedang berjalan). Jika tidak, Anda tidak bisa menentukan ke arah mana pointer bergerak.

Kode yang dikomentari:

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

Klik di sini untuk kode dengan nol menggantikan byte nol. Setiap kejadian $0tidak boleh diganti dengan nol.

Sunting : Sekarang mendukung input kosong dan menekan trailing newline.

Output tanpa batas sekarang didukung. (403 byte)


Saya agak berharap bahwa saya akan menempatkan <code>dan <tape>selanjutnya satu sama lain (meskipun akan lebih banyak karakter) sehingga transisi ke penerjemah SMBF akan lebih mudah, jika saya pernah memutuskan untuk melakukan itu.
mbomb007

14

TI-BASIC, 264 byte

Karena keterbatasan dalam TI-BASIC, ini sebenarnya tidak memenuhi syarat untuk tantangan ini karena melanggar aturan 2; RAM kalkulator sangat terbatas, dan melakukan sesuatu seperti 30000->dim(L1(saya menggunakan L1 untuk stack / array) akan memaksanya untuk melempar ERR:MEMORY. Dengan demikian, tumpukan / array dimulai pada ukuran 1 dan tumbuh jika pointer menunjuk ke elemen melewati ujungnya. Itu juga melanggar aturan 3, karena sudah melanggar aturan 2 jadi saya mungkin juga tidak repot dengan batas ukuran sel.

Ngomong-ngomong, mungkin masih bisa bermain golf ... Saya sudah membuat satu atau dua suntingan untuk tujuan itu sejak pertama kali dikirim, tetapi jika versi di bawah ini tidak berfungsi, kembalilah ke pengeditan mulai 6 Mei '15 dan gunakan itu kode sebagai gantinya. Juga, karena benar-benar tidak ada ASCII di TI-BASIC, ini mengambil angka dari berbagai ukuran (dan apa pun yang mengembalikan angka, seperti variabel atau ekspresi) sebagai input, dan menghasilkan angka pada gilirannya.

Gunakan SourceCoder untuk membuatnya menjadi file .8xp kemudian kirimkan ke kalkulator Anda dengan TI-Connect atau TILP atau apalah, dan jalankan dengan memasukkan program brainfuck Anda dalam tanda kutip ganda diikuti oleh titik dua dan apa pun yang Anda beri nama program TI-BASIC. Misalnya, jika Anda menamakannya BrainF, Anda akan menjalankan program seperti ini: "brainfuck goes here":prgmBRAINF. Jika Anda memiliki shell pada calc Anda yang memotong perintah lain ketika mendeteksi prgmtoken, meskipun, melakukan hal ini: "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

Jika Anda tidak memiliki cara untuk menghubungkan kalkulator Anda ke komputer dan ingin mengetikkan ini di-kalk sebagai gantinya (Saya tidak bisa membayangkan mengapa Anda ingin, tapi saya ngelantur) perhatikan bahwa itu ->adalah STO>tombol di atas ON kunci, ~adalah simbol negatif di sebelah ENTER, dan untuk mengganti semua instance L<number>dengan token daftar yang sesuai ditemukan di2ND -> <number on keypad>

Berkat thomas-kwa (setidaknya, saya pikir itu nama pengguna Stack-nya) untuk membantu saya mengoptimalkan ini, terutama dengan [dan ]instruksi.


1
Apakah Anda membutuhkan orangtua Ans+S?
Zacharý

@ Zacharý Tangkapan bagus, tidak. Saya pasti tidak yakin tentang cara kerja PEMDAS atau sesuatu ... Saya akan menahan diri dari mengedit, karena sudah begitu lama sehingga pasti tidak layak untuk menaikkan posting ini ke depan dan karena dua byte reduksi tidak akan memberikan jawaban keuntungan apa pun atas yang lain lol.
MI Wright

1
Saya ingat sekitar 2-3 tahun yang lalu ketika saya menggunakan program ini untuk menafsirkan Brainf *** pada kalkulator saya. Dan, ini pertanyaan interpretasi, saya pikir itu harus di atas jujur.
Zacharý

1
Sebenarnya, saya pikir seluruh baris itu bisa S-sum(not(cumSum(L4(Ans)=seq(L4(X),X,Ans+1,dim(L4->S. ( a-a=0). Dan hei, jangan khawatir tentang melupakan SATU urutan operasi di sini, saya telah melihat banyak orang lupa urutan operasi untuk %(mod) pada tantangan.
Zacharý

1
Oh sial, ya. Oke, itu memberikan setidaknya 10 byte sejak jika dapat dibuat satu-liner juga, ditambah beberapa hal lain ... mungkin juga mengedit, kalau begitu. Anda telah membuat saya mengeluarkan kalkulator saya untuk pertama kalinya dalam waktu setahun untuk memeriksa barang-barang ini, haha
MI Wright

13

Python 275 248 255

Saya memutuskan untuk mencobanya.

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
Rapi, Anda menghasilkan kode sumber python menggunakan brainfuck.

1
Anda dapat menghapus 1 char, "import sys as s" dan ganti "sys" menjadi "s" di sisanya
YOU

Perhatikan bahwa ini sebenarnya 247 karakter. (Lihat ruang jahat setelah exec t?). Jika Anda menggunakan ujung S.Mark dan juga membuat seluruh forsiklus menjadi satu baris, Anda dapat mengecilkan ini menjadi 243 karakter.
Oleh Prypin

Ini gagal pada input apa pun yang berisi [], program bf yang sepele namun valid. Saya telah menyarankan edit yang memperbaiki ini, tetapi meningkatkan jumlah karakter. Untuk mengurangi jumlah karakter lebih lanjut, Anda bisa from sys import *, dan gunakan 'i+=1,...'.split(',')sebagai ganti ['i+=1',...].
stan

7
Saya akan +1, tetapi banyak perbaikan telah disarankan dan tidak diterapkan.
mbomb007

12

Haskell, 457 413 karakter

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

Kode ini "mengkompilasi" program BF menjadi IOaksi bentuk State -> IO Statenegara adalah ritsleting pada string yang tak terbatas.

Sedih karena saya harus mengeluarkan 29 karakter untuk mematikan buffering. Tanpa itu, ia berfungsi, tetapi Anda tidak melihat petunjuknya sebelum Anda harus mengetikkan input. Compiler itu sendiri ( b,, fdan k) hanya 99 karakter, runtime ( #dan %) adalah 216. Driver w / inisial menyatakan 32 lainnya.

>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 

pembaruan 2011-02-15: Saran JB yang dimasukkan, melakukan sedikit perubahan nama, dan diperketatmain


1
Anda harus bisa mendapatkan buffering dari just IO, dan argumen dari just System(-19). Masalah buffering menggangguku juga, karena spec tidak benar-benar menyebutkannya dan jawaban terpilih bahkan tidak melakukan I / O. Jika Anda harus menyimpannya, mungkin lebih singkat hFlushsetelah setiap penulisan daripada mengubah mode buffering global (-34 + 15).
JB

11

Conveyor, 953

Ini mungkin kode terindah yang pernah Anda lihat:

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
Bisakah Anda menambahkan penjelasan dan tautan ke implementasi? Saya ingin mengerti keindahannya. ;)
DLosc

1
Yah, saya sedang mengembangkannya, ada kompiler dan penjelasan yang sangat buruk di github.com/loovjo/Conveyor . Sumbernya cukup mudah dibaca jika Anda ingin memahaminya.
Loovjo

9

C 284 362 (Dari file)

#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);}

Bilangan prima:

Primes hingga: 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
Tekan tombol apa saja untuk melanjutkan . . .

Dikompilasi dan dijalankan dengan sukses VS2008

Solusi asli gagal mengenali loop yang awalnya diatur ke nol. Masih ada ruang untuk bermain golf. Tetapi akhirnya menyelesaikan program Nomor Perdana.

Tidak Terkumpul:

#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);
}

Tes:

Halo Dunia

Rot13


Apakah Anda memeriksa pointer yang sama ( l) setiap kali Anda mengulang? Saya pikir Anda seharusnya memeriksa lokasi kepala saat ini ( p).
Alexandru

Saya meneruskan pointer ke buffer dan pointer ke stream. Ia memeriksa pada akhir loop untuk melihat apakah pointer ldi buffer telah mencapai nol dan memecah yang lain itu me-reset aliran kembali ke loop asli [. Ini diperlukan untuk [loop bersarang .
snmcdonald

1
Ya. Saya pikir juga begitu. Anda seharusnya tidak memeriksa nilai pada penunjuk saat pertama kali masuk dalam loop, tetapi nilai pada penunjuk saat ini. Periksa tes dalam pertanyaan. Program Anda hang.
Alexandru

1
Anda bisa menggantinya break;elsedengan return;.
Alexandru

3
Saya pikir Anda bisa menggantinya (c==62)?a:bdengan (c-62)?b:a.
Alexandru

9

PHP 5.4, 296 294 273 263 261 209 191 183 178 166 karakter:

Saya mencobanya tanpa menggunakan eval, tetapi akhirnya saya harus menggunakannya

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

Semua perintah berfungsi. Ini sangat menyalahgunakan variabel variabel, dan menyebarkan peringatan. Namun, jika seseorang mengubah php.ini mereka ke memadamkan peringatan (atau pipa stderr ke / dev / null), ini berfungsi dengan baik.

Verifikasi (Ini adalah contoh "Hello World!" Dari Wikipedia ): http://codepad.viper-7.com/O9lYjl

Tidak Digubah, 367 365 335 296 267 karakter:

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

Ini harus dijalankan melalui baris perintah: 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

Konversi instruksi yang cukup mudah dan kemudian Invoke-Expression.

Sejarah:

  • 2011-02-13 22:24 (220) Upaya pertama.
  • 2011-02-13 22:25 (218) 3e4lebih pendek dari 30000.
  • 2011-02-13 22:28 (216) Line break yang tidak perlu. Mencocokkan bilangan bulat sebagai ganti karakter lebih pendek.
  • 2011-02-13 22:34 (207) Menggunakan indeks ke tabel hash bukan switch.
  • 2011-02-13 22:40 (205) Lebih baik dilemparkan ke string menghapus dua tanda kurung.
  • 2011-02-13 22:42 (204) Tidak perlu spasi setelah argumen ke Write-Host.

8

C, 333 karakter

Ini adalah juru bahasa BF pertama saya dan golf pertama yang harus saya debug.

Ini menjalankan pembangkit bilangan prima pada Mac OS X / GCC, tetapi tambahan #include<string.h>mungkin diperlukan dengan biaya 19 karakter lebih jika definisi implisit dari strchrtidak terjadi untuk bekerja pada platform lain. Juga diasumsikan O_RDONLY == 0. Selain itu, meninggalkan intkeluar dari deklarasi Mmenyimpan 3 karakter tapi itu tampaknya tidak sesuai C99. Sama dengan yang ketiga *di b().

Ini tergantung pada rincian pengkodean ASCII. Operator Brainfuck adalah semua pasangan pelengkap yang dipisahkan oleh jarak 2 dalam ruang kode ASCII. Setiap fungsi dalam program ini mengimplementasikan sepasang operator.

#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]();
}

Saya pikir Anda dapat menyusutkan lebih banyak dengan menggunakan notasi 'e' untuk semua angka besar.
luser droog

@luser: Saya awalnya terkejut juga, tetapi bahasa dan kompiler tidak akan membiarkan itu. Saya berhasil menyusutkan 4 karakter lain dengan tweak, dan menggunakan #definetabel fungsi bukannya mungkin juga akan terser. Saya suka nomor 333 dan tabel: v).
Potatoswatter

Oh benar Aku seharusnya tahu itu. E-notasi dalam produksi untuk konstanta floating-point, sedangkan deklarasi membutuhkan integer. BTW, ini mungkin curang, tetapi periksa nieko.net/projects/brainfuck untuk versi Urban Müller. Keuntungan terbesar tampaknya merupakan penggunaan berat ||.
luser droog

8

CJam, 75 byte

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

Cobalah online: pembalikan string , Hello World .

Penjelasan

Mengambil kode pada baris pertama STDIN dan memasukkan semua baris di bawahnya.

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.

Bagaimana dengan daftar ajaib itu?

"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.

Daftar yang dihasilkan adalah sebagai berikut:

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)

Kami menghasilkan potongan untuk +dan >dari orang-orang untuk -dan <, hanya dengan mengubah parens kiri (CJam ini “penurunan”) ke dalam parens kanan ( “peningkatan” CJam ini).


Jawaban terpendek & pemenang terbesar
Jack Giffin

7

F #: 489 karakter

Program berikut tidak melompat pada instruksi '[' / ']', tetapi memindai kode sumber untuk token yang cocok berikutnya. Ini tentu saja membuatnya agak lambat, tetapi masih dapat menemukan bilangan prima di bawah 100. Jenis integer F # tidak meluap tetapi membungkus.

Ini versi singkatnya:

[<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 jahat adalah bahwa program primes.bf tersedak pada baris baru windows. Untuk menjalankannya, saya harus menyimpan nomor input ke dokumen teks yang diformat UNIX dan memasukkannya ke program dengan pipa:

interpret.exe prime.bf < number.txt

Sunting: memasuki Alt + 010 diikuti oleh Enter juga berfungsi di Windows cmd.exe

Ini versi yang lebih panjang:

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

Saya memecahkan masalah Enter dengan tidak menekannya tetapi Ctrl + J :-)
Joey

Ctrl + J tidak bekerja untuk saya, tetapi memasukkan Alt + 010 diikuti oleh Enter.
cfern

7

Delphi, 397 382 378 371 366 364 328 karakter

Makan Delphi ini!

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.

Di sini kode yang sama, indentasi dan komentar:

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.

Yang ini memakan waktu beberapa jam, karena itu bukan jenis kode yang biasanya saya tulis, tetapi nikmatilah!

Catatan: Tes utama berfungsi, tetapi tidak berhenti di 100, karena berbunyi # 13 (CR) sebelum # 10 (LF) ... apakah kiriman lain juga mengalami masalah ini ketika berjalan pada CRLF OS?


Wow! Saya tidak akan pernah berharap untuk mengalahkan C dengan Delphi! Tidak sampai Anda menerapkan ide-ide saya untuk CI kira ;-)
PatrickvL

7

C, 260 + 23 = 283 byte

Saya membuat program C yang dapat ditemukan di sini .

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++;}}

Harus dikompilasi melalui gcc -D"q(a,b)"="*c-a||(b);" -o pmmbf pmmbf.cdan dapat dipanggil sebagai berikut: di pmmbf ",[.-]" 30000mana argumen pertama (dikutip) berisi bf-program untuk dijalankan, yang kedua menentukan seberapa besar rekaman seharusnya.


1
Saya pikir Anda perlu menambahkan 23 karakter ke hitungan Anda untuk -D"q(a,b)"="*c-a||(b);"opsi, karena tampaknya (setidaknya pemahaman saya, setidaknya) akan membantu Anda mengecilkan kode Anda.
Gareth

Opsi ini termasuk dalam teks yang diposting. Alasannya adalah untuk menghindari kata define- kata yang panjang dan baris baru, tetapi saya tidak berpikir itu benar-benar halal. Pokoknya dengan kutipan, komentar, dan gcc -Dsaya tidak melihat keuntungannya sama sekali.
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);}

Jalankan sebagai ./a.out primes.bf

Versi Tidak Serigala:

#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

Saya akui bahwa saya mendaur ulang program lama saya (tetapi harus mengubahnya sedikit, karena versi lama tidak memiliki input, tetapi memeriksa kesalahan ...).

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

Menjalankan kalkulator primes baik-baik saja.

Saya melihat sekarang bahwa Alexandru memiliki jawaban yang memiliki beberapa kesamaan. Saya akan memposting jawaban saya, karena saya pikir ada beberapa ide baru di dalamnya.


5

C (gcc) Linux x86_64, 884 621 525 487 439 383 358 354 byte

*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);}

Cobalah online!

Ini adalah JIT yang mengkompilasi kode BF ke dalam bahasa mesin x86_64 saat runtime. Ini melakukan terjemahan lurus sehingga sering terjadi urutan seperti >>>, <<<, +++dan--- tidak berkoalisi menjadi petunjuk yang lebih cepat.

Versi yang kurang golf:

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

Membaca dari file. Lulus tes PRIME.BF.

Penggunaan: ./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;}}


Dipformat ulang:

#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. Buffer Anda terlalu kecil. Ukuran program juga terlalu kecil.
Alexandru

Saya membuat kesalahan ketik, diperbaiki. Apa yang Anda maksud dengan ukuran program? Jika Anda maksudkan ukuran file maks, Anda tidak menentukan minimum yang harus ditangani.
jtjacques

4

Lua, 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]"))()

Versi yang bisa dibaca:

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

Bekerja dengan sempurna

Lua, 478, tanpa tali beban

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

Versi yang dapat dibaca:

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 bytes

Yah, itu butuh waktu. Saya bermain self-interpreter Brainfuck dengan ... bukan saya.

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

4

Penarikan , 594 byte

Singkatnya: Recall tidak memiliki operator aritmatika dalam arti klasik, ia hanya memiliki operasi bitwise. Anda tidak bisa hanya "menambahkan satu", dll. Ingat juga didasarkan pada stack.

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

Contoh 1: Cetak sesuatu

Memasukkan:

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

Keluaran:

PPCG rocks!

Contoh 2: Output angka kuadrat hingga 100

Memasukkan:

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

Keluaran:

0
1
4
9
16
25
36
49
64
81
100

Contoh ini mungkin memerlukan beberapa menit untuk dieksekusi dan mungkin menyebabkan pesan "tab ini dibekukan". Abaikan itu dan tunggu.


4
Domain situs web Anda telah kedaluwarsa. Juga, jawaban ini tidak bersaing, karena bahasanya lebih baru daripada tantangan.
mbomb007

3

OCaml (lex), 497 karakter

OCamllex adalah bagian dari distribusi standar 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}

Simpan sebagai b.mll dan jalankan dengan

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

Saya tidak suka parsing dengan tangan, jadi saya menggunakan generator lexer yang disediakan. Dari token baca, kami menulis fungsi untuk program brainf * ck keseluruhan.


3

C # (2861 char, ~ 84 baris)

Ini bukan solusi tercantik untuk masalah ini, dan mungkin tidak semua 'Golf-ish', karena saya tidak peduli dengan panjang seperti yang seharusnya saya lakukan. (Saya tidak menghapus komentar atau ruang kosong ekstra.) Saya hanya ingin mencoba sesuatu dalam bahasa baru, untuk melihat apakah saya bisa. Jika saya melakukannya lagi, saya akan membatalkan penggunaan tumpukan untuk kembali dari ']' dan hanya melihat ke belakang. Jalankan tanpa argumen baris perintah, ia menjalankan program hello world yang diberikan dalam deskripsi masalah. Ia menerima satu argumen baris perintah, nama file program yang akan dijalankan.

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

        }
    }

}

Sunting: Menghapus referensi yang tidak digunakan.


1
@ mbomb007 - Diperbarui. Benar-benar lupa saya bahkan melakukan ini. (Bahkan tidak menyadari ada orang yang membaca pertanyaan-pertanyaan lama ini)
theB

Tidak hanya orang-orang masih membacanya, mereka masih menjawab dan golf mereka.
mbomb007

3

C (gcc) , 273 268 byte

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");};

Cobalah online!

-5 Terima kasih untuk ceilingcat

Mengambil input dari stdin.

Ini sedikit bergantung pada lingkungan, tetapi cukup konsisten. Ini secara efektif solusi eval untuk c. Itu menulis program C yang sesuai untuk file wc, mengkompilasinya, dan menjalankannya sebagai executable yang diinginkan. Jadi sebagai efek bonus ini sebenarnya mengkompilasi kode bf dan meninggalkan a.outsebagai biner untuk itu. Perhatikan bahwa tergantung pada sistem Anda mungkin perlu memodifikasi string terakhir. Khususnya sebagian besar kompiler windows c memanggil executable default "a.exe". Untungnya sejauh yang saya tahu, mereka semua memiliki panjang yang sama sehingga bytecount sama. (meskipun jika Anda tidak memiliki cc yang ditentukan, Anda mungkin perlu menambahkan huruf seperti gcc ke perintah kompilasi, menambahkan 1 byte).

Saya sadar bahwa utas ini agak lama, tetapi saya belum melihat solusi gaya C ini, jadi saya pikir saya akan menambahkannya.



2

[SUNTING]

C ++ 11, 355, dibaca dari file:

#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]();
}

Uji

http://ideone.com/b7vO4

[VERSI LAMA]

C ++ 11, 391, untuk menjalankannya: 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]();
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.