Brainf'i yorumlayın ***


113

Brainfuck programını yorumlamak için en kısa programı en sevdiğiniz dile yazın . Program bir dosyadan okunur. Giriş ve çıkış standart giriş ve standart çıkıştır.

  1. Hücre boyutu: 8 bit işaretsiz. Taşma tanımsız.
  2. Dizi boyutu: 30000 bayt (daire içine alınmamış)
  3. Hatalı komutlar girişin bir parçası değil
  4. Yorumlar # ile başlar ve satır sonuna kadar devam eder Yorumlar'ın şeyi olmayan+-.,[]<>
  5. EOF sembolü yok

Çok iyi bir test bulunabilir burada . Bir sayı okur ve sonra bu sayıya kadar asal sayıları yazdırır. Bağlantı çürümesini önlemek için, kodun bir kopyası:

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

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

Örnek çalışma:

$ 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) hafızanın büyüklüğünü netleştirmelisiniz 2) daire içine
alınmış bir hafızadır

3
İki kategori olması gerekip gerekmediğini merak ediyorum: eval kullanan (veya derlemek için çalışan) programlar ve yapmayanlar.
MtnViewMark

34
Birinin bunu beyninde cevapladığını görmek isterim.
Hannesh

3
"EOF sembolü yok" ne anlama geliyor? ,EOF üzerinde çalışırken hücre değerinin değişmeden kaldığını ? Yoksa ,EOF üzerinde çalışırken bir değer seçmek bize kalmıştır. Yoksa EOF tanımsız davranış tamamen mı?
Martin Ender

3
Aynı şekilde, birileri 30k hücrelerini iki tarafa da bırakmaya çalıştığında ne olmalı? Teyp kafası yerinde kalmalı mı yoksa bu tanımsız davranış mı?
Martin Ender

Yanıtlar:


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

Bu, hello.bf ve primes.bf komutlarını kusursuz biçimde çalıştırır:

$ 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

Başlatma: Perl çeviri tablosuna yapılan opcode içinde saklanır %c. Okunabilir form şöyle görünür:

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

Adım 1: $_Çeviri programını kullanarak program girişini sıkıştırın ve Perl koduna dönüştürün. Yorumlar undefbu adımda otomatik olarak çıkarılır (ile değiştirilir ).

Adım 2: Tüm $b[$p]olayları açın

Adım 3: Kullanarak programı başlatın eval.


Sadece Perl'in kullanmak qwtanımlamak için sözdizimi %c(Söyleyecek gerekecek 7 daha az karakter için iyi - doğrudan print+chr$b[$p]ve ord(getc)olsa)
mob

18 kişiyi kurtardım… teşekkürler! (bir dakika içinde güncelleniyor)
JB

1
@olivecoder Dünyada ne hakkında konuşuyorsunuz?
JB

% C tablosu ilk satırda bildirilir ve tanımlanır; karakterleri mükemmel bir şekilde açıklanır.
JB

@JB hey, yanlışlıkla cevabınıza oy verdim ve kilitliydi, aşağıyı oylayabilmem için bunu düzenleyebilir misiniz?
Sikloheksanol.

67

Python (değerlendirme yok), 317 bayt

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

9
Bu güzel bir ses parçası efendim
globby

-1 bayt while b*c[c[0]]and j<1ile değiştirirsenizwhile b*c[c[0]]*(j<1)
Daniil Tutubalin

50

16 bit 8086 makine kodu: 168 bayt

İşte base64 kodlu sürümü, dönüştürün ve 'bf.com' olarak kaydedin ve Windows komut isteminden çalıştırın: 'bf progname'

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

DÜZENLE

İşte çalıştırılabilir oluşturmak için bazı assembler (A86 tarzı) (Orijinal kaynağı yanlış yerleştirdiğim için bunu tersine mühendislik yapmak zorunda kaldım!)

    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

Programın kaynak kodunu ekledim. Bf olmayan karakterlerin programın yok sayılmak yerine çıkmaktan çıkmasına neden olduğunu gördüm. Bunu düzeltmek kolay ve bunu insanların kendileri için bir egzersiz olarak bırakacağım.
Skizz

Linux ELF sürüm 166 bayt, 10 yıl önce aldığımı hatırlıyorum, burada muppetlabs.com/~breadbox/software/tiny
Emmanuel,

39

brainfuck , 843 691 bayt

Düzenleme: Bu tekrar ziyaret etmeye karar verdi ve bayt golf kapalı şaşırtıcı bir dizi yolunu buldu

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

Bu , isteğe bağlı code!inputolduğu biçimde girdi alır !input. Aynı zamanda, negatif hücreleri kullanmadan negatif hücreleri simüle eder ve hücrelere depolayabilir (30000-(length of code+6))/2.

Çevrimiçi deneyin!


Bunu doğru yaptığımdan emin olmak için, eğer bu programı bu programla çalıştırırsam, onu 5 seviyeye yerleştirebilirim ve yine de 262 uzunluğundaki kod girişlerini kullanabilirim.
Draco18s

@ Draco18s Her bir iç içe tercümanın boyutu katlanarak arttığından, bundan önce 30000 hücrenin tükendiğinden şüpheleniyorum. Sanırım 2, belki 3 seviye derinlikte olacak
Jo King

Hatta 3 derin bile komik saçma olurdu.
Draco18

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

Biraz okunabilir versiyonu:

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

Gördüğünüz gibi, utanmadan ev sahibi dile çeviri fikrinizi çaldım ve sonra onu çalıştırmak için eval kullandım.


Sen sıfıra karşılaştıran bir bayt bayt kapalı tıraş edebilirsiniz >0yerine eşitlik test daha: !=0. Özellikler imzasız ve taşma tanımsız.
anonim korkak

3e4aynı zamanda zıt olarak da çalışacak30000
anonim korkak

@Charlie: Teşekkürler. Adil olmakla birlikte, kodu yazarken "imzasız" demedi. Gerçekten de 3e4 yazabileceğini bilmiyordum. Bu çok iyi bir nokta ve bilmek güzel.
sepp2k

File.read($*.pop).bytes-> $<.bytesçok çalışmalı
Arnaud Le Blanc

1
: Yakut 1.8.7 bir değişmez karma oluşturmak için daha da kısa bir sözdizimi vardır {?a,"foo"}, eşdeğerdir {?a=>"foo"}. Ve burada test aslında yerini alabildiğini göstermektedir File.read($*.pop).bytesile $<sorunsuz. Aynı zamanda her şeyi bir şeye eval"a[0]..."+$<.bytes.map{?.,"putc a[i]",...}*";"dizmek, çözümü bir kaç karakter daha da kısaltır.
Ventero

26

İkili Lambda Hesabı 112

Aşağıdaki altıgen dökümde gösterilen program

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

girdisinin bir Brainfuck programından oluşmasını bekler (bunu sadece, -. + <>] [) ve ardından a], ardından Brainfuck programına ait girdiler arasından ayıran 0,1,4 bitlere bakabilirsiniz.

Yukarıdaki hex dökümünü xxd -r> bf.Blc ile kaydedin.

Https://tromp.github.io/cl/cl.html adresinden bir blc yorumlayıcısı alın.

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

Selam Dünya!


1
Bu neden var bile? Görünüşe göre araştırma alanında bile var . Oo
Isiah Meadows

Yani bu, yorumlanmış brainfuck programlarıyla çalışmaz mı?
kamoroso94

Hayır, önce yorumları çıkarmadan olmaz.
John Tromp

18

Retina 0.8.2 , 386 391 386 bayt

Kod, yazdırılamayan NUL ( 0x00) karakterleri içerir. Aynı zamanda henüz süper golf oynamadı, çünkü zaten çok yavaş, ve eğer daha çok golf oynarsam, bitirmem ne kadar sürecek bilemiyorum. Asal bulma örneğinde zaman aşımına uğrar.

Çevrimiçi tercümanda veya programımda hatalar olabilir (yeni satırlarda çıkışta görünmüyor mu?).

Gibi girdi alır <code>│<input>. Hayır, bu bir boru değil ( |). Unicode karakteri U+2502. Kod ayrıca Unicode karakterlerini kullanır ÿ▶◀├║. Tüm ASCII karakterlerinin girişini desteklemek için Unicode karakterler kullanılır. Bu nedenle, bu karakterlerin koddan ASCII olmayan bir karakterle ayrılması gerekir.

Çevrimiçi deneyin

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

Not orada son bir yeni satır var.

Kısa açıklama:

0x00Sonsuz olan kaset için sıfırlar kullanılır. İlk değiştirme, tercümanı formda kurar ▶<code>│<input>├<output>║▶<tape>, burada birinci kod için işaretçi, ikincisi ise bant için işaretçidir.

ÿolduğu 0xFFHarf Çevirisi için kullanılan (uygulamak için kullanılan (255), +ve -) sıfıra geri etrafında hücreleri sarmak için.

yalnızca okunabilirlik için kullanılır (programın ortasında durduğunda veya programı yürütme sırasında görmek istiyorsanız). Aksi halde, işaretçinin hangi yöne hareket ettiğini söyleyemezsiniz.

Yorumlanan Kod:

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

Boş baytların yerine sıfır bulunan kod için burayı tıklayın . Hiçbir oluşumu $0null ile değiştirilmemelidir.

Düzenleme : Şimdi boş girişi destekler ve izleyen yeni satırı bastırır.

Sonsuz çıktı şimdi desteklenmektedir. (403 bayt)


Ben biraz ben koymuş diliyorum <code>ve <tape>bir SMBF tercüman geçiş kolay olurdu böylece şimdiye kadar bunu yapmaya karar verirseniz, (o daha fazla karakter olurdu gerçi) yanyana.
mbomb007

14

TI-BASIC, 264 bayt

TI-BASIC’teki sınırlamalar nedeniyle, bu kural 2'yi ihlal ettiği için bu zorunluluk için yeterli değildir; hesap makinelerinin RAM'leri çok sınırlıdır ve 30000->dim(L1(yığın / dizi için L1 kullanıyorum) gibi bir şey yapmak onu atmaya zorlayacaktır ERR:MEMORY. Böylece, yığın / dizi 1 büyüklüğünde başlar ve işaretçi sonunu geçen bir öğeye işaret ediyorsa büyür. Aynı zamanda kural 3'ü de bozuyor, çünkü zaten kural 2'yi bozuyor, bu yüzden hücre boyutu sınırını zorlamadım.

Bu arada, muhtemelen hala golf oynayabilir mi ... Bu arada, ilk gönderimden bu yana bir veya iki düzenleme yaptım, ancak aşağıdaki sürüm işe yaramazsa, 6 Mayıs’taki düzenlemeye geri dönün ve bunu kullanın. yerine kod. Ayrıca, TI-BASIC'te ASCII olmadığından, bu herhangi bir boyuttan (ve bir sayı, değişken veya ifade gibi bir sayı) giriş olarak alır ve sayıları sırayla verir.

Bir .8xp dosyası oluşturmak için SourceCoder'ı kullanın, sonra onu TI-Connect veya TILP veya benzeri bir şeyle hesap makinenize gönderin ve bir bülten tarafından takip edilen çift tırnak içine beyin Teli Programını dahil ederek ve TI-BASIC programını ne adlandırdıysanız çalıştırın. Örneğin, Brainf olarak adlandırdı eğer böyle bir programı çalıştırmak istiyorum: "brainfuck goes here":prgmBRAINF. Eğer algıladığında diğer komutlar yakaladığını da kalk bir kabuk varsa prgmbelirteci olsa da, şöyle yapın: "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

Eğer bilgisayara hesap bağlayan bir yol var ve bunun yerine on-calc bu tip dışarı istemiyorsanız notu (siz isterdim neden bilemiyorum, ama sapmak) ->olan STO>ON yukarıdaki düğme tuşu, ~ENTER’in yanındaki negatif semboldür ve tüm örneklerini, L<number>üzerinde bulunan karşılık gelen liste2ND -> <number on keypad>

Sayesinde Thomas-kwa özellikle birlikte, beni bu duruma yardımcı olmak için (en azından ben onun Stack adı olduğunu düşünüyorum) [ve ]talimatlar.


1
Etraftaki parenlere ihtiyacın var Ans+Smı?
Zacharý

@ Zacharý İyi yakaladın, hayır. PEMDAS'ın nasıl çalıştığından ya da bir şeyden emin olmam gerekiyor olmalı ... Düzenlemekten kaçınacağım, çünkü, bu yazıyı öne doğru çarpmaya değmeyecek kadar uzun bir zaman geçti çünkü iki byte Azaltma, cevabın diğerlerine göre herhangi bir avantaj sağlamayacak.
MI Wright,

1
Hesaplamamda Brainf *** 'u yorumlamak için bu programı kullandığımda 2-3 yıl önce hatırlıyorum. Ve bu bir yorumlayıcı beyin sorusu *** sorusu, dürüst olmak gerekirse en üstte olması gerektiğini düşünüyorum.
Zacharý

1
Aslında, tüm çizginin olabileceğini düşünüyorum S-sum(not(cumSum(L4(Ans)=seq(L4(X),X,Ans+1,dim(L4->S. ( a-a=0). Ve hey, buradaki BİR ÇALIŞMA sırası sırasını unutmaktan endişe etmeyin, bir grup insanın %(mod) için yapılan operasyon sırasını bir meydan okumadan unuttuğunu gördüm .
Zacharý

1
Oh dang, evet. Tamam, bu da en az 10 bayt verir çünkü if bir tek astar da yapılabilir, artı başka şeyler de olabilir. Bu şeyleri kontrol etmek için bir yıl gibi ilk defa hesap makinemi kırbaçlamıştın, haha
MI Wright

13

Python 275 248 255

Denemeye karar verdim.

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
Düzgün, sen beyinbeyi kullanarak python kaynak kodu üretiyorsun.

1
Sen, "s olarak import sys" 1 kömürü şerit ve geri kalanı "sys" için "s" yerine geçebilir
SİZE

Bunun aslında 247 karakter olduğunu unutmayın. (Sonra pis alana bakın exec t?). Eğer kullanırsanız S.Mark 'in ucu ve aynı zamanda bütün haline forbir hizaya döngüsü, sen 243 karakter için bu daraltabilir.
Oleh Prypin,

Bu [], geçerli ama önemsiz bir bf programı içeren herhangi bir girdi için başarısız olur . Bunu düzelten, ancak karakter sayısını artıran bir düzenleme önerdim. Karakter sayısını daha da azaltmak için from sys import *, 'i+=1,...'.split(',')yerine ve kullanabilirsiniz ['i+=1',...].
stand

7
Ben +1, ama birçok gelişme önerildi ve uygulanmadı.
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

Bu kod BF programını " sonsuz bir ipte fermuar olduğu IO" şeklindeki bir harekete dönüştürür State -> IO State.

Tamponlamayı kapatmak için 29 karakter harcamam gerektiğine üzüldüm. Bunlar olmadan çalışır, ancak girdi yazmadan önce istemleri görmezsiniz. Derleyicinin kendisi ( b, fve k) yalnızca 99 karakterdir, çalışma zamanı ( #ve %) 216'dır. Sürücü başka bir durumda 32.

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

>./BF HELLO.BF 
Hello World!

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

güncelleme 2011-02-15: JB'nin önerilerini birleştirdi, biraz yeniden adlandırdı ve sıkıldımain


1
Arabelleğe almayı sadece IOve argümanları sadece System(-19) ile elde edebilmelisiniz. Tamponlama sorunu da beni rahatsız ediyor, çünkü özellik gerçekten belirtmiyor ve en çok oy alan cevap G / Ç yapmıyor bile. Eğer varsa gerekir saklayacağım, muhtemelen daha kısa hFlushküresel tamponlama modunu (+15 -34) değiştirmek daha her yazılmasından sonra.
JB,

11

Taşıyıcı, 953

Bu şimdiye kadar göreceğiniz en güzel kod olabilir:

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
Bir açıklama ve bir uygulamanın bağlantısını ekleyebilir misiniz? Ben güzelliği anlamak istiyorum. ;)
DLosc

1
Şu anda onu geliştiriyorum, bir derleyici ve github.com/loovjo/Conveyor adresinde çok kötü bir açıklama var . Anlamak istiyorsanız kaynak oldukça okunabilir.
Loovjo

9

C 284 362 (Bir dosyadan)

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

Asal sayılar:

En fazla: 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
Devam etmek için herhangi bir tuşa basın . . .

Derlendi ve başarıyla VS2008 koştu

Orijinal çözüm, başlangıçta sıfıra ayarlanmış döngüleri tanıyamadı. Hala golf oynamak için yer var. Ancak nihayet Asal Sayı programını çözer.

Ungolfed:

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

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

Testler:

Selam Dünya

rot13


lHer döngüde aynı göstergeyi ( ) mi kontrol ediyorsunuz? Sanırım kafanın şu anki yerini kontrol etmeniz gerekiyor ( p).
Alexandru

İşaretçiyi arabelleğe ve işaretçiyi akışa iletirim. Tampondaki imlecin lsıfıra ulaşıp ulaşmadığını görmek için döngünün sonunda kontrol eder ve başka bir koparsa akışı tekrar orijinal döngüye döndürür [. Bu iç içe [döngüler için gereklidir .
snmcdonald

1
Evet. Ben de öyle düşünmüştüm. Döngüye ilk girişte göstergenin değerini kontrol etmemelisiniz, ancak geçerli göstergenin değerini kontrol etmelisiniz. Sorudaki testi kontrol edin. Programın kilitleniyor.
Alexandru

1
Sen değiştirebilirsiniz break;elsetarafından return;.
Alexandru

3
Sana yerini alabilir mi (c==62)?a:bsahip (c-62)?b:a.
Alexandru

9

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

Eval kullanmadan bir şans verdim ama sonunda kullanmak zorunda kaldım

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

Bütün komutlar çalışıyor. Bu, değişken değişkenleri şiddetli bir şekilde kötüye kullanır ve uyarılar atar. Bununla birlikte, eğer biri php.ini'sini susturma uyarılarıyla (ya da stderr / / dev / null yönündeki boruları) değiştirirse, bu harika olur.

Doğrulama ( Wikipedia'dan "Merhaba Dünya!" Örneği ): http://codepad.viper-7.com/O9lYjl

Ungolfed, 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);

Bu komut satırı üzerinden çalıştırılmalıdır: 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

Talimatların ve daha sonra oldukça basit dönüşüm Invoke-Expression.

Tarih:

  • 2011-02-13 22:24 (220) İlk deneme.
  • 2011-02-13 22:25 (218) 3e4daha kısa 30000.
  • 2011-02-13 22:28 (216) Gereksiz satır sonları. Karakterler yerine tamsayılarla eşleştirme daha kısadır.
  • 2011-02-13 22:34 (207) Kullanılan dizinler yerine karma tablolarına yerleştirildi switch.
  • 2011-02-13 22:40 (205) İpin daha iyi kullanılması, iki parantezi kaldırır.
  • 2011-02-13 22:42 (204) Tartışmadan sonra boşluğa gerek yok Write-Host.

8

C, 333 karakter

Bu benim ilk BF tercümanım ve aslında hata ayıklamak zorunda olduğum ilk golf.

Bu, asal sayı üretecini Mac OS X / GCC'de çalıştırır, ancak #include<string.h>bunun açık tanımı strchrbaşka bir platformda işe yaramazsa , 19 karakter daha ek ücrete tabi olabilir. Ayrıca, varsayar O_RDONLY == 0. Bunun yanı sıra, 3 karakterlik tasarruf intbeyannamesi dışında bırakılmak, Mancak bu C99 uyumlu görünmüyor. Üçte Aynı *içinde b().

Bu ASCII kodlamanın özelliklerine bağlıdır. Brainfuck operatörleri, ASCII kod alanında 2 mesafeyle ayrılmış tamamlayıcı çiftlerdir. Bu programdaki her fonksiyon bir çift operatör uygular.

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

Tüm büyük sayılar için 'e' notasyonunu kullanarak daha fazla küçültebileceğinizi düşünüyorum.
kullanıcı

@ luser: Başlangıçta ben de şaşırdım, ancak dil ve derleyici buna izin vermiyor. Tweaks ile başka bir 4 karakter küçültmeyi #definebaşardım ve işlev tablosu yerine bunun kullanılması da ters olur. Sadece 333 sayısını ve masayı seviyorum: v).
Patates suyu

Ah, doğru. Bunu gerçekten bilmeliydim. E-notasyon kayan nokta sabiti için üretimdedir, beyan ise tamsayı gerektirir. Btw , bu hile olabilir, ama Urban Müller sürümü için nieko.net/projects/brainfuck göz atın . En büyük kazancın yoğun kullanımı gibi görünüyor ||.
kullanıcı

8

CJam, 75 bayt

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

Çevrimiçi deneyin: string reverser , Hello World .

açıklama

STDIN'in ilk satırında kodu alır ve altındaki tüm satırlara giriş yapar.

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.

Peki ya büyülü liste?

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

Ortaya çıkan liste aşağıdaki gibidir:

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)

Biz Pasaj oluşturmada +ve >için olanlardan -ve <basitçe (CJam yönettiği “artım”) sağ Pars içine (CJam yönettiği “eksiltme”) Sol parens değiştirerek.


En kısa cevap ve en büyük kazanan
Jack Giffin

7

F #: 489 karakter

Aşağıdaki program '[' / ']' talimatlarında atlamaz, ancak bir sonraki eşleşen belirtecin kaynak kodunu tarar. Elbette bu onu yavaşlatır, ancak 100'ün altındaki primerleri hala bulabilir. F # tamsayı türleri taşma yerine değil de sarılır.

İşte kısa versiyonu:

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

Kötü bir şakası, primes.bf programının pencerelerin yeni hatlarında boğulmasıydı. Çalıştırmak için giriş numarasını UNIX formatlı bir metin belgesine kaydetmem ve programa bir boru ile beslemem gerekiyordu:

interpret.exe prime.bf < number.txt

Düzenleme: Alt + 010 girdikten sonra Enter tuşuna basıp Windows cmd.exe'de de çalışır

İşte daha uzun sürüm:

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

Ctrl + J benim için işe yaramadı, ama Alt + 010 girdikten sonra Enter yaptım.
cfern

7

Delphi, 397 382 378 371 366 364 328 karakter

Bu Delphi'yi ye!

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.

İşte aynı kod, girintili ve yorum yaptı:

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.

Bu bir kaç saatimi aldı, çünkü normalde yazdığım bir kod değildi, ama tadını çıkar!

Not: Asal test çalışır, ancak 100'de durmaz, çünkü # 10 (LF) 'den önce # 13 (CR) okur ... başka gönderiler CRLF OS'lerde çalışırken de bu soruna neden olur mu?


Vaov! Delphi ile hiçbir zaman C'yi kısaca beklemem! Fikirlerimi
CI'ye

7

C, 260 + 23 = 283 bayt

Burada bulunabilecek bir C programı yarattım .

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

Üzerinden derlenmeli gcc -D"q(a,b)"="*c-a||(b);" -o pmmbf pmmbf.cve şu şekilde çağrılabilir: pmmbf ",[.-]" 30000birinci argüman (alıntı) çalıştırılacak bf programını içerir, ikincisi bandın ne kadar büyük olması gerektiğini belirler.


1
Bu -D"q(a,b)"="*c-a||(b);"seçenek için sayınıza 23 karakter eklemeniz gerektiğini düşünüyorum , çünkü kodunuzu küçültmek için (en azından sınırlı anlayışa göre).
Gareth,

Seçenek yayınlanan metne dahil edilir. Bunun nedeni uzun laflardan defineve yeni satırlardan kaçınmaktır , ama bunun gerçekten daha iyi olduğunu sanmıyorum. Neyse tırnak, yorum ve gcc -Dhiçbir şekilde avantaj göremiyorum.
Patates suyu

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 olarak çalıştırın

Ungolfed Sürümü:

#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

Eski bir programımı geri dönüştürdüğümü itiraf ediyorum (ancak eski sürümün girişi olmadığı için hata değiştirmek zorunda kaldım, ama hata kontrolü ...).

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

Asal hesap makinesini iyi çalıştırır.

Şimdi Alexandru'nun bazı benzerlikleri olan bir cevabı olduğunu görüyorum. Yine de cevap yazacağım çünkü bunda yeni fikirler olduğunu düşünüyorum.


5

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

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

Çevrimiçi deneyin!

Bu, çalışma zamanında BF kodunu x86_64 makine diline derleyen bir JIT'dir. Bu nedenle yaygın olarak sekansları meydana gelen düz bir çevirisini gerçekleştirir >>>, <<<, +++ve ---daha hızlı bir talimat halinde birleşmiş değildir.

Daha az golf oyunu:

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

Bir dosyadan okur. PRIME.BF testini geçti.

Kullanım: ./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;}}


reformasyon:

#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. Tamponunuz çok küçük. Programın boyutu da çok küçük.
Alexandru

Bir yazım hatası yaptım düzeltildi. Program büyüklüğü ile ne demek istiyorsunuz? Maksimum dosya boyutunu kastediyorsanız, işlemesi gereken bir minimum belirtmediniz.
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]"))()

Biraz okunabilir versiyonu:

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

Mükemmel çalışıyor

Lua, 478, yüksüz

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

Okunabilir sürüm:

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 bayt

Bu biraz zaman aldı. Bir Brainfuck kendi kendine tercüman tarafından golf yaptım ... ben değil.

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

4

Geri Çağırma , 594 bayt

Kısacası: Geri Çağırma'nın klasik anlamda aritmetik operatörleri yoktur, sadece bitsel işlemleri vardır. Sadece "bir tane" ekleyemezsiniz. Geri çağırma ayrıca kesinlikle yığın tabanlıdır.

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

Örnek 1: Bir şeyler yazdırın

Giriş:

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

Çıktı:

PPCG rocks!

Örnek 2: 100'e kadar çıktı kare sayıları

Giriş:

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

Çıktı:

0
1
4
9
16
25
36
49
64
81
100

Bu örnek, yürütülmesi birkaç dakika sürebilir ve "bu sekme donmuş" iletisine neden olabilir. Bunu görmezden gelin ve bekleyin.


4
Web sitenizin etki alanının süresi doldu. Ayrıca, bu cevap rakip değildir, çünkü dil zorluktan daha yenidir.
mbomb007 23.03.16

3

OCaml (lex), 497 karakter

OCamllex, OCaml'in standart dağılımının bir parçasıdır.

{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 olarak kaydedin ve ile çalıştırın

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

Elle ayrıştırmayı sevmiyorum, bu yüzden verilen lexer jeneratörünü kullandım. Okunan belirteçlerden, tüm brainf * ck programı için bir işlev oluştururuz.


3

C # (2861 karakter, ~ 84 satır)

Bu, problemin en güzel çözümü değil ve muhtemelen “Golf-ish” de değildi, çünkü olması gerektiği gibi uzunluğa ilgi duymadım. (Yorumları veya fazladan beyaz alanı kaldırmadım.) Yeni bir dilde bir şey denemek istedim, yapıp yapamayacağımı görmek için. Tekrar yapsaydım, ']' den dönmek için yığının kullanımını bırakırdım ve geriye bakardım. Komut satırı argümanları olmadan çalıştır, problem tanımında verilen merhaba dünya programını çalıştırır. Çalıştırılacak programın dosya adı olan bir komut satırı argümanını kabul eder.

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

        }
    }

}

Düzenleme: Kullanılmayan referanslar kaldırıldı.


1
@ mbomb007 - Güncelleme. Tamamen unuttum bunu bile yaptım. (Hatta bu eski soruları okuyan birisinin farkında bile değildim)
saat

Sadece insanlar hala onları okumakla kalmıyor, yine de cevaplıyor ve golf oynuyorlar.
mbomb007

3

C (gcc) , 273 268 bayt

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

Çevrimiçi deneyin!

-5 ceilingcat sayesinde

Stdin'den girdi alır.

Bu, çevreye biraz güvenir, ancak oldukça tutarlıdır. Bu etkili c için eval bir çözümdür. Wc dosyasına uygun bir C programı yazar, onu derler ve istenen çalıştırılabilir olarak çalıştırır. Böylece, bir bonus efekti olarak, bu aslında bf kodunu derler ve a.outbunun için bir ikili dosya olarak bırakır . Sisteme bağlı olarak, son dizgiyi değiştirmeniz gerekebileceğini unutmayın. Özellikle çoğu pencere c derleyicisi varsayılan çalıştırılabilir "a.exe" yi çağırır. Neyse ki söyleyebileceğim kadarıyla, hepsinin uzunluğu aynı, yani bayt sayısı aynı. (cc tanımınız yoksa, derleme komutuna gcc gibi bir mektup eklemeniz gerekebilir, 1 bayt ekleyin).

Bu iş parçacığının biraz eski olduğunun farkındayım, ancak henüz bu C çözüm tarzını görmedim, bu yüzden ekleyeceğimi düşündüm.



2

[DÜZENLE]

C ++ 11, 355, dosyadan okur:

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

Ölçek

http://ideone.com/b7vO4

[ESKİ VERSİYON]

C ++ 11, 391, çalışmasını görmek için: 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]();
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.