Brainfを解釈する***


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)その他の詳細について
11

3
2つのカテゴリがあるはずかと思います。evalを使用する(またはコンパイルするためにシェルアウトする)プログラムとそうでないプログラムです。
MtnViewMark

34
誰かがブレインファックでこれに答えてくれるのを楽しみにしています。
ハネシュ

3
「EOFシンボルなし」とはどういう意味ですか?,EOFを試してみると、セルの値は変わらないのですか?または、,EOFを試すときに値を選択するのは私たち次第ですか?または、EOFの未定義の動作は完全にありますか?
マーティンエンダー

3
同様に、誰かが3万個のセルをどちらかの側に残そうとするとどうなりますか?テープヘッドはそのままにしておくべきですか、それともこの未定義の動作ですか?
マーティンエンダー

回答:


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

初期化:オペコードからPerlへの変換テーブルはに保存され%cます。読み取り可能なフォームは次のようになります。

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

ステップ1:$_変換テーブルを使用して、プログラム入力を読み、Perlコードに変換します。undefこのステップでは、コメントは自動的に削除されます(に置き換えられます)。

ステップ2:すべての$b[$p]オカレンスを圧縮解除する

ステップ3:を使用してプログラムを起動しevalます。


ただ、Perlの使用qwを定義する構文を%c直接-良い7つの少ない文字(あなたが言うことがありますためprint+chr$b[$p]ord(getc)いえ、)
暴徒

救われた18人をカウントします。(1分後に更新)
JB

1
@olivecoder一体何について話しているのですか?
JB

%cテーブルは、最初の行で宣言および定義されています。そのキャラクターは完全に説明されています。
JB

@JBちょっと、あなたの答えに誤って投票を押し下げて、それが固定されています。これを編集して、反対票を取り消すことができますか?
シクロヘキサノール。

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

9
それは美しいノイズです。先生
グロビー14

-1あなたが交換した場合、バイトwhile b*c[c[0]]and j<1while b*c[c[0]]*(j<1)
ダニール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以外の文字が無視されるのではなく、プログラムを終了させることに気づきました。それを簡単に修正できますので、それを人々が自分で行うための演習として残しておきます。
スキッツ

私はここで、10年前、私はLinuxのELFバージョン166バイトを持って覚えてmuppetlabs.com/~breadbox/software/tiny
エマニュエル・

39

brainfuck843 691バイト

編集:これを再検討することを決定し、バイトをオフにゴルフする驚くべき数の方法を発見しました

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

これはcode!input!inputオプションの形式で入力を受け取ります。また、負のセル自体を使用せずに負のセルをシミュレートし、(30000-(length of code+6))/2セルまで保存できます。

オンラインでお試しください!


ただ、私はこのプログラムで、このプログラムを実行した場合、私は、この権利を得たことを確認するために私の巣て、5つのレベルの深さと長さ、まだ262のコードの入力を処理できた
Draco18s

@ Draco18sネストされた各インタープリターのサイズは指数関数的に増加するため、その前に30000セルを使い果たすと思われます。私はあなたが深い、多分3レベル2を取得したいと思います
ジョー・キング

深さ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。仕様には符号なしと書かれており、オーバーフローは未定義です。
匿名のco

3e4反対にも動作します30000
匿名の臆病者

@チャーリー:ありがとう。公平であるとはいえ、コードを書いたときに「符号なし」とは言いませんでした。正直なところ、3e4を書くことができるとは知りませんでした。それは非常に良い点であり、知っておくべきことです。
sepp2k

File.read($*.pop).bytes->も動作する$<.bytesはずです
アルノールブラン

1
Ruby 1.8.7には、リテラルハッシュを作成するためのさらに短い構文があります。{?a,"foo"}これはと同等{?a=>"foo"}です。そして、ここでテストしたところ、実際に問題なく交換できることがわかりFile.read($*.pop).bytesました$<。また、すべてをインライン化するとeval"a[0]..."+$<.bytes.map{?.,"putc a[i]",...}*";"、ソリューションがさらに数文字短くなります。
ヴェンテロ

26

バイナリラムダ計算112

以下の16進ダンプに示されているプログラム

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プログラムの入力が続くと想定しています。

上記の16進ダンプをxxd -r> bf.Blcで保存します

https://tromp.github.io/cl/cl.htmlからblcインタープリターを取得します

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 14

だから、これはコメントされたブレインファックプログラムでは動作しませんか?
kamoroso94

いいえ、最初にコメントを削除する必要があります。
ジョントロンプ

18

網膜0.8.2386の 391 386バイト

コードに印刷できないNUL(0x00)文字が含まれています。また、すでに本当に遅いので、まだスーパーゴルフされていません。そして、もっとゴルフをするなら、終わるまでにどれくらいかかるかわかりません。素数発見サンプルでタイムアウトしたように見えます。

オンラインインタープリターまたは私のプログラムにバグがある可能性があります(主要な新しい行が出力に表示されませんか?)。

のような入力を受け取ります<code>│<input>。いいえ、それはパイプ(|)ではありません。それはUnicode文字U+2502です。コードは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>で設定します。最初のコードはコードへのポインターで、2番目のコードはテープへのポインターです。

ÿ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ヌルに置き換えないでください。

編集:空の入力をサポートし、末尾の改行を抑制します。

無限出力がサポートされるようになりました。(403バイト)


私は一種の私が置かだろうと希望<code><tape>SMBFインタプリタに移行することが容易になるように、私が今までそれを行うことにした場合、(それはそれ以上の文字になるだろうが)お互いに隣接しています。
mbomb007

14

TI-BASIC、264バイト

TI-BASICの制限のため、これはルール2に違反するため、実際にはこの課題に適格ではありません。電卓のRAMは非常に制限されており、30000->dim(L1(スタック/配列にL1を使用します)ようなことをすると、強制的にがスローされますERR:MEMORY。そのため、スタック/配列はサイズ1から始まり、ポインタが要素の終わりを指している場合は大きくなります。また、すでにルール2に違反しているため、ルール3にも違反しているため、セルサイズの制限を気にする必要はありません。

おそらく、まだゴルフをしている可能性があります...最初に送信してから1つまたは2つの編集を行いましたが、以下のバージョンが機能しない場合は、15年5月6日から編集に戻って使用します代わりにコード。また、TI-BASICには実際にはASCIIがないため、これは任意のサイズの数値(および変数や式などの数値を返すもの)を入力として受け取り、順番に数値を出力します。

SourceCoderを使用して.8xpファイルにビルドし、TI-ConnectまたはTILPなどを使用して計算機に送信し、ブレインファックプログラムに二重引用符を付け、コロンとTI-BASICプログラムに名前を付けて実行します。たとえば、BRAINFという名前を付けた場合、次のようなプログラムを実行します"brainfuck goes here":prgmBRAINFprgmただし、トークンを検出したときに他のコマンドをインターセプトするシェルがcalcにある場合は、これを実行します"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

あなたがコンピュータに電卓を接続する方法を持っているし、代わりに-CALCこれを入力したくない場合は(あなたがしたいと思いますなぜ私が想像することはできませんが、私は脱線)->STO>ON上記のボタンをキー~は、ENTERの横にある負の記号であり、のすべてのインスタンスL<number>を、対応するリストトークンに置き換えます2ND -> <number on keypad>

おかげでトーマス・クワ私は特にして、これを最適化するための手助け(少なくとも、私はそれが彼のスタックのユーザー名だと思う)[]の指示。


1
周りに括弧が必要Ans+Sですか?
ザカリー

@ザカリー良いキャッチ、いいえ。私はPEMDASの仕組みや何かについて確信が持てなかったに違いありません。しかし、編集を控えることになります。削減は、他の人よりも有利な答えを与えるものではありません。
MIライト

1
2-3年前、このプログラムを使用して電卓でBrainf ***を解釈したときのことを思い出します。そして、それは解釈の脳みそ***の質問です、正直に言うと一番上にあるべきだと思います。
ザカリー

1
実際には、行全体がになる可能性があると思いますS-sum(not(cumSum(L4(Ans)=seq(L4(X),X,Ans+1,dim(L4->S。(a-a=0)。ここで、1つの操作順序を忘れることを心配しないでください%。チャレンジの(mod)の操作順序を忘れる人が大勢います。
ザカリー

1
ああ、そうだね。さて、ifを1行にすることもできるので、少なくとも10バイトは解放されます。さらに、他のいくつかのことも編集できます。あなたは私が(笑)、このようなものをチェックするために毎年のように最初に私の電卓をサッと取り出し作った
MIライト

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を使用してpythonソースコードを生成しています。

1
1文字を削除し、「sysをsとしてインポート」し、残りの「sys」を「s」に置き換えることができます
-YOU

これは実際には247文字です。(exec t?の後の厄介なスペースを参照してください)。S.Markのヒントを使用し、forサイクル全体を1行にすると、これを243文字に縮小できます。
オレPrypin

これは[]、有効な些細なbfプログラムであるを含む入力では失敗します。これを修正する編集を提案しましたが、文字数を増やします。文字数をさらに減らすには、の代わりにfrom sys import *を使用します。'i+=1,...'.split(',')['i+=1',...]
ブースバイ

7
したいの+1ですが、多くの改善が提案されており、実装されていません。
mbomb007

12

Haskell、457413文字

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のアクションに変換します。

バッファリングをオフにするために29文字を費やさなければならなかったことを悲しい。それらがなくても動作しますが、入力を入力する前にプロンプ​​トは表示されません。コンパイラ自体(bf、及びはk)わずか99文字、ランタイム(ある#%)別の32の初期状態/ Wドライバ216です。

>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年2月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をコンパイルして正常に実行しました

元のソリューションでは、最初にゼロに設定されたループを認識できませんでした。まだゴルフの部屋。しかし、最終的に素数プログラムを解決します。

ゴルフをしていない:

#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)を確認することになっていると思います。
アレクサンドル

バッファーへのポインターとストリームへのポインターを渡します。ループの終わりにチェックしてl、バッファ内のポインタがゼロに達したかどうかを確認し、それ以外の場合は、ストリームを元のループにリセットします[。これはネストされた[ループに必要です。
snmcdonald

1
うん。私はそうだと思いました。最初にループに入るときにポインターの値をチェックするのではなく、現在のポインターの値をチェックする必要があります。質問のテストを確認してください。プログラムがハングします。
アレクサンドル

1
あなたは置き換えることができますbreak;elseによってreturn;
アレクサンドル

3
私はあなたが交換することができると思います(c==62)?a:b(c-62)?b:a
アレクサンドル

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をスケルチ警告に変更する(またはstderrを/ dev / nullにパイプする)場合、これはうまく機能します。

検証(Wikipediaの「Hello World!」の例):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)3e4は未満30000です。
  • 2011-02-13 22:28(216)不要な改行。文字ではなく整数でのマッチングが短くなります。
  • 2011-02-13 22:34(207)の代わりにハッシュテーブルへのインデックスを使用しましたswitch
  • 2011-02-13 22:40(205)文字列へのキャストが改善され、2つの括弧が削除されました。
  • 2011-02-13 22:42(204)への引数の後にスペースは必要ありませんWrite-Host

8

C、333文字

これは私の最初のBFインタープリターであり、実際にデバッグしなければならなかった最初のゴルフです。

これは、Mac OS X / GCCで素数ジェネレーターを実行し#include<string.h>ますが、暗黙の定義がstrchr別のプラットフォームで機能しない場合、19文字のコストで追加が必要になる場合があります。また、を想定していO_RDONLY == 0ます。それとは別にint、宣言をM省略すると3文字保存されますが、C99に準拠していないようです。の3番目*と同じb()です。

これは、ASCIIエンコードの詳細に依存します。Brainfuck演算子はすべて、ASCIIコード空間で2の距離で区切られた相補的なペアです。このプログラムの各関数は、一対の演算子を実装しています。

#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ことに成功しました。関数テーブルの代わりにaを使用することもおそらくより簡単です。数字333とテーブル:v)が好きです。
ジャガイモのたたき

ああ、そう。本当に知っておくべきだった。E表記法は浮動小数点定数のプロダクションにありますが、宣言には整数が必要です。ところで、これは不正行為の可能性がありますが、UrbanMüllerのバージョンについてはnieko.net/projects/brainfuckをチェックしてください。最大の利益はの大量使用のようです||
luser droog

8

CJam、75バイト

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

オンラインで試してください:string reverserHello 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)

我々はのためのスニペットを生成+して>のものからを-して<、単純に右括弧(CJamの「増分」)に左括弧(CJamの「減少」)を変更することもできます。


最短回答&最大の勝者
ジャックギ

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

厄介なのは、primes.bfプログラムがWindowsの改行でチョークすることです。これを実行するには、入力番号をUNIX形式のテキストドキュメントに保存し、パイプでプログラムに入力する必要がありました。

interpret.exe prime.bf < number.txt

編集:Windows cmd.exe でもAlt + 010に続けてEnterを入力すると機能します

長いバージョンは次のとおりです。

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

Enterキーを押さずにCtrl + Jで問題を解決しました:
Joey

Ctrl + Jは機能しませんでしたが、Alt + 010に続けてEnterを入力しました。
11

7

デルファイ、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.

これは私が通常書くコードの種類ではないので、数時間かかりましたが、楽しんでいます!

注:プライムテストは機能しますが、#10(LF)の前に#13(CR)を読み取るため、100で停止しません...


うわー!Delphiを使って簡潔にCに勝るとは思ってもみませんでした!CIの推測に私のアイデアを適用するまで;
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プログラムが含まれ、2番目の引数はテープの大きさを決定します。


1
-D"q(a,b)"="*c-a||(b);"オプションのカウントに23文字を追加する必要があると思います。それは(少なくとも私の知る限りでは)コードの縮小に役立つように思えるからです。
ガレス

このオプションは、投稿されたテキストに含まれています。その理由は、長い単語defineや改行を避けるためですが、それは本当にコーシャーではないと思います。とにかく引用符で、コメント、そしてgcc -D私は全く利点が表示されません。
ジャガイモのたたき

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には、いくつかの類似点がある答えがあることがわかりました。とにかく多くの回答を投稿します。新しいアイデアがあると思うからです。


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

オンラインでお試しください!

これは、実行時にBFコードをx86_64マシン言語にコンパイルするJITです。これには、一般的のようなシーケンスを発生ストレート変換を行い>>><<<+++および---高速化命令に合体されていません。

ゴルフの少ないバージョン:

// 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対30000。バッファが小さすぎます。プログラムのサイズも小さすぎます。
アレクサンドル

タイプミスを修正しました。プログラムサイズとはどういう意味ですか?最大ファイルサイズを意味する場合、処理する最小サイズを指定していません。
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

私は手で構文解析するのが好きではないので、提供された字句解析器ジェネレーターを使用しました。読み取ったトークンから、brainf * ckプログラム全体の関数を作成します。


3

C#(2861文字、〜84行)

これは問題の最も美しい解決策ではなく、おそらく「ゴルフっぽい」すべてではありません。(コメントや余分な空白を削除しませんでした。)できるかどうかを確認するために、新しい言語で何かを試してみたかっただけです。もう一度やったら、 ']'から戻るためのスタックの使用をやめて、振り返ってみます。コマンドライン引数なしで実行すると、問題の説明で指定されているhello worldプログラムが実行されます。実行するプログラムのファイル名である1つのコマンドライン引数を受け入れます。

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 ceilingcatに感謝

stdinから入力を受け取ります。

これは環境に少し依存していますが、かなり一貫しています。これは実質的にcの評価ソリューションです。適切なCプログラムをファイルwcに書き込み、コンパイルして、目的の実行可能ファイルとして実行します。したがって、ボーナス効果として、これは実際にbfコードをコンパイルし、a.outそのバイナリとして残します。システムによっては、最後の文字列を変更する必要がある場合があることに注意してください。特に、ほとんどのWindows cコンパイラは、デフォルトの実行可能ファイル「a.exe」を呼び出します。幸いなことに、私が知る限り、それらはすべて同じ長さであるため、バイトカウントは同じです。(ただし、ccが定義されていない場合は、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.