두뇌 해석하기 ***


113

brainfuck 프로그램 을 해석하기 위해 가장 좋아하는 언어로 가장 짧은 프로그램을 작성하십시오 . 파일에서 프로그램을 읽습니다. 입력 및 출력은 표준 입력 및 표준 출력입니다.

  1. 셀 크기 : 8 비트 부호없는. 오버 플로우가 정의되지 않았습니다.
  2. 배열 크기 : 30000 바이트 (원이 아님)
  3. 잘못된 명령은 입력의 일부가 아닙니다
  4. 주석은 #로 시작하고 라인의 끝에 연장 에 댓글 모든되지 않습니다+-.,[]<>
  5. EOF 기호 없음

여기서 아주 좋은 테스트를 찾을 수 있습니다 . 숫자를 읽은 다음 해당 숫자까지 소수를 인쇄합니다. 링크 썩음을 방지하려면 다음 코드를 복사하십시오.

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

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

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

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

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

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

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

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

 >+<--

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

 [
  >+

  <-

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

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


  >>>


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

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

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


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


  <<

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

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

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

  >>




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

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


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

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

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

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

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

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

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

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

   <-
  ]

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

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


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



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

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

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

예제 실행 :

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

5
1) 메모리 크기 2) 메모리가 동그라미로 표시됩니다. 4) 다른 세부 정보
Nakilon

3
두 가지 범주가 있는지 궁금합니다. eval (또는 셸 아웃 컴파일)을 사용하는 프로그램과 그렇지 않은 프로그램.
MtnViewMark

34
나는 누군가가 brainfuck에서 이것에 대답하는 것을보고 싶습니다.
Hannesh

3
"EOF 기호 없음"은 무엇을 의미합니까? ,EOF를 시도 할 때 셀 값이 변경되지 않습니까? 아니면 ,EOF를 시도 할 때 가치를 선택하는 것은 우리에게 달려 있습니까? 아니면 EOF 정의되지 않은 동작이 모두 있습니까?
Martin Ender

3
마찬가지로, 누군가가 30k 셀을 양쪽으로 남겨 두려고하면 어떻게됩니까? 테이프 헤드가 제자리에 남아 있어야합니까 아니면이 정의되지 않은 동작입니까?
Martin Ender

답변:


46

펄, 120138

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

이것은 hello.bf와 primes.bf를 완벽하게 실행합니다 :

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

초기화 : opcode에서 Perl 로의 변환 테이블이에 저장됩니다 %c. 읽을 수있는 형식은 다음과 같습니다.

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

1 단계 : $_번역 테이블을 사용하여 Slurp 프로그램 입력 및 Perl 코드로 변환 undef이 단계에서는 주석이 자동으로 제거됩니다 (로 대체 됨 ).

2 단계 : 모든 $b[$p]항목 압축 해제

3 단계 :을 사용하여 프로그램을 시작합니다 eval.


그냥 펄의 사용 qw정의하는 구문을 %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
f(u,c,k)
Joel Cornett의

9
그것은 하나의 아름다운 소음입니다
globby

-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 문자로 인해 프로그램이 무시되는 대신 종료되는 것으로 나타났습니다. 쉽게 고칠 수 있고 사람들이 스스로 할 수 있도록 연습으로 남겨 두겠습니다.
Skizz

나는 10 년 전에 리눅스 ELF 버전 166 바이트를 얻었다는 것을 기억한다. 여기 muppetlabs.com/~breadbox/software/tiny
Emmanuel

39

brainfuck , 843 691 바이트

편집 : 이것을 다시하기로 결정하고 바이트를 골라내는 놀라운 방법을 발견했습니다.

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

이것은 선택적인 형태 code!input로 입력을받습니다 !input. 또한 네거티브 셀 자체를 사용하지 않고 네거티브 셀을 시뮬레이션하고 최대 (30000-(length of code+6))/2셀 까지 저장할 수 있습니다 .

온라인으로 사용해보십시오!


이 프로그램으로이 프로그램을 실행하면 5 단계 깊이로 중첩 할 수 있으며 길이는 262 인 코드 입력을 처리 할 수 ​​있습니다.
Draco18s

@ Draco18s 중첩 된 각 인터프리터의 크기가 기하 급수적으로 증가하기 때문에 그 전에 30000 개의 셀이 부족한 것 같습니다. 나는 당신이 2, 아마도 3 레벨을 얻을 것이라고 생각합니다
Jo King

깊숙한 3 명조차도 유쾌하게 바보입니다.
Draco18s

27

루비 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과 비교하여 바이트 바이트를 줄일 수 있습니다 !=0. 사양은 부호가 없으며 오버플로는 정의되어 있지 않습니다.
익명 겁쟁이

3e4반대로도 작동합니다30000
익명의 겁쟁이

@Charlie : 감사합니다. 공평하지만 코드를 작성할 때 "부호 없음"이라고 말하지 않았습니다. 나는 솔직히 3e4를 쓸 수 있다는 것을 몰랐습니다. 그것은 매우 좋은 지적이며 알기에 좋습니다.
sepp2k

File.read($*.pop).bytes-> $<.bytes작동해야 함
Arnaud Le Blanc

1
Ruby 1.8.7에는 리터럴 해시를 빌드하는 구문이 훨씬 짧 {?a,"foo"}습니다 {?a=>"foo"}. 그리고 여기 테스트하는 것은 당신이 실제로 대체 할 수 있음을 보여준다 File.read($*.pop).bytes$<아무 문제없이. 또한 모든 것을 인라인으로 인라인 eval"a[0]..."+$<.bytes.map{?.,"putc a[i]",...}*";"하면 다른 몇 문자로 솔루션이 단축됩니다.
Ventero

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 만 보임)과 a], Brainfuck 프로그램의 입력으로 구성 될 것으로 예상합니다.

xxd -r> bf.Blc를 사용하여 위의 16 진 덤프를 저장하십시오.

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

그래서 이것은 주석이 달린 brainfuck 프로그램과 함께 작동하지 않습니까?
kamoroso94

아니오, 먼저 의견을 제거하지 마십시오.
존 트롬 프

18

레티 나 0.8.2 , 386 391 386 바이트

코드에 인쇄 할 수없는 NUL ( 0x00) 문자 가 포함되어 있습니다 . 그것은 이미 정말 느리기 때문에 아직 슈퍼 골프가 아니며, 더 골프를 타면 얼마나 오래 걸릴지 모르겠습니다. 프라임 찾기 샘플에서 시간이 초과 된 것으로 나타납니다.

온라인 통역사 또는 내 프로그램에 버그가있을 수 있습니다 (결과에 새로운 줄이 표시되지 않습니까?).

같은 입력을 <code>│<input>받습니다. 아니요, 파이프 ( |) 가 아닙니다 . 유니 코드 문자 U+2502입니다. 이 코드는 유니 코드 문자도 사용합니다 ÿ▶◀├║. 모든 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테이프에는 0 이 사용되며 무한합니다. 첫 번째 대체는 인터프리터를 형식으로 설정합니다. ▶<code>│<input>├<output>║▶<tape>첫 번째 는 코드의 포인터이고 두 번째는 테이프의 포인터입니다.

ÿ0xFF(255)로, 음역 (구현 +및 사용 -)에서 셀을 다시 0으로 감싸는 데 사용 됩니다.

가독성을 위해서만 사용됩니다 (프로그램이 중간에 중지되었거나 실행 중 프로그램을 보려는 경우). 그렇지 않으면 포인터가 어떻게 움직이는 지 알 수 없습니다.

주석 처리 된 코드 :

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

널 바이트 대신 0이있는 코드를 보려면 여기클릭하십시오 . 발생이 $0널 (null)로 바뀌지 않아야합니다.

편집 : 이제 빈 입력을 지원하고 후행 줄 바꿈을 억제합니다.

무한 출력이 지원됩니다. (403 바이트)


나는 ( <code>그리고 <tape>더 많은 문자가 될지라도) 서로 옆에 서로를 배치하여 SMBF 통역사로의 전환이 더 쉬울 수 있기를 바랍니다.
mbomb007

14

TI-BASIC, 264 바이트

TI-BASIC의 한계로 인해 규칙 2를 위반하므로 실제로이 과제에 적합하지 않습니다. 계산기의 RAM은 매우 제한되어 있으며 30000->dim(L1(스택 / 배열에 L1을 사용 합니다)와 같은 작업을 수행 하면 강제로 ERR:MEMORY. 따라서 스택 / 배열은 크기가 1에서 시작하여 포인터가 끝을 지나서 요소를 가리키면 커집니다. 이미 규칙 2를 위반하고 있기 때문에 규칙 3을 위반하므로 셀 크기 제한을 방해하지 않을 수 있습니다.

아마 여전히 골프를 칠 수 있었을 것입니다 ... 처음 제출 한 이후로 한두 번 편집을 끝 냈지만 아래 버전이 작동하지 않으면 15 년 5 월 6 일부터 편집으로 돌아가서 사용하십시오. 대신 코드. 또한 TI-BASIC에는 실제로 ASCII가 없으므로 모든 크기의 숫자 (및 변수 또는 표현식과 같은 숫자를 반환하는 숫자)를 입력으로 사용하여 숫자를 차례로 출력합니다.

SourceCoder 를 사용 하여 .8xp 파일로 빌드 한 다음 TI-Connect 또는 TILP 등으로 계산기에 전송하고 Brainfuck 프로그램을 큰 따옴표로 묶은 다음 콜론 및 TI-BASIC 프로그램 이름을 붙여서 실행하십시오. 예를 들어 BRAINF라는 이름을 지정하면 다음과 같은 프로그램을 실행합니다 "brainfuck goes here":prgmBRAINF. calc에 prgm토큰을 감지했을 때 다른 명령을 가로채는 쉘이 있다면 다음과 같이하십시오 "brainfuck goes here" -> press ENTER -> prgmBRAINF.

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

당신이 당신의 컴퓨터에 계산기를 연결하는 방법이 대신에-CALC이을 입력하지 않으려면 노트 (당신이 원하는 것 내가 왜 상상할 수 없다,하지만 난 빗나가 다) ->는 IS STO>를 ON 위의 버튼을 키 ~는 ENTER 옆의 음수 기호이며 모든 인스턴스를 L<number>해당하는 목록 토큰으로 바꿉니다.2ND -> <number on keypad>

특히 and 지침을 사용 하여이를 최적화하는 데 도움을 준 thomas-kwa (적어도 그의 스택 사용자 이름이라고 생각합니다) 덕분 입니다.[]


1
당신은 주위에 parens가 필요 Ans+S합니까?
Zacharý

@ Zacharý 잘 잡아라. PEMDAS의 작동 방식에 대해 확신이 없었을 것입니다 ...하지만 편집을 자제 할 것입니다. 축소는 다른 lol보다 어떤 종류의 이점도 대답하지 않습니다.
MI Wright

1
2-3 년 전이 프로그램을 사용하여 계산기에서 Brainf ***를 해석했을 때를 기억합니다. 그리고, 그것은 해석 적 인 두뇌 문제입니다. 나는 정직하기 위해서는 최상위에 있어야한다고 생각합니다.
Zacharý

1
사실, 나는 전체 라인이 될 수 있다고 생각합니다 S-sum(not(cumSum(L4(Ans)=seq(L4(X),X,Ans+1,dim(L4->S. ( a-a=0). 그리고 야, 여기에 하나의 작업 순서를 잊어 버릴 염려가 없습니다. 나는 많은 사람들 %이 도전에 대한 (mod)에 대한 작업 순서를 잊는 것을 보았습니다 .
Zacharý

1
아 당장 좋아, if는 one-liner뿐만 아니라 다른 것들도 만들 수 있기 때문에 적어도 10 바이트를 줄입니다. 이 물건을 확인하기 위해 1 년 만에 처음으로 계산기를 꺼내 보았습니다. 하하
MI Wright

13

파이썬 275 248 255

나는 그것을 시도하기로 결정했습니다.

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

12
깔끔하게, 당신은 brainfuck를 사용하여 파이썬 소스 코드를 생성하고 있습니다.

1
1 개의 문자, "sys를 s로 가져 오기"를 제거하고 나머지 부분에서 "sys"를 "s"로 교체 할 수 있습니다
YOU

이것은 실제로 247 자입니다. ( exec t? 뒤에 불쾌한 공간을보십시오 ). 당신이 사용하는 경우 S.Mark 의 팁을 또한 전체 수 있도록 for한 줄에주기를, 당신은 243 개 문자에이를 축소 할 수 있습니다.
Oleh Prypin

이것은 []유효하지만 사소한 bf 프로그램을 포함하는 모든 입력에서 실패합니다 . 이 문제를 해결하지만 문자 수를 늘리는 편집을 제안했습니다. 문자 수를 더 줄이려면을 대신 from sys import *사용할 수 있습니다 . 'i+=1,...'.split(',')['i+=1',...]
boothby

7
나는 +1했지만 많은 개선이 제안되었고 구현되지 않았다.
mbomb007

12

하스켈, 457 413 자

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

이 코드는 BF 프로그램을 상태가 무한 문자열의 지퍼 IO형식 State -> IO State의 동작 으로 "컴파일" 합니다.

버퍼링을 끄려면 29자를 소비해야했기 때문에 슬프다. 그것들이 없으면 작동하지만 입력을 입력하기 전에 프롬프트가 표시되지 않습니다. 컴파일러 자체 ( b,, fk)는 99 자이고 런타임 ( #%)은 216입니다. 초기 상태의 드라이버는 다른 32입니다.

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

>./BF HELLO.BF 
Hello World!

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

2011-02-15 업데이트 : JB의 제안을 통합하고 약간의 이름을 바꾸고 강화했습니다.main


1
just에서 버퍼링을 얻을 수 IO있고 인수는 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 284362 (파일에서)

#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 35 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
계속하려면 아무 키나 누르십시오. . .

VS2008 컴파일 및 실행

원래 솔루션은 처음에 0으로 설정된 루프를 인식하지 못했습니다. 아직도 골프장. 그러나 마지막으로 소수 번호 프로그램을 해결합니다.

언 골프 드 :

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

테스트 :

안녕하세요 월드

썩음 13


l반복 할 때마다 동일한 포인터 ( ) 를 확인하고 있습니까? 머리의 현재 위치를 확인해야한다고 생각합니다 ( p).
Alexandru

버퍼에 포인터를, 스트림에 포인터를 전달합니다. 루프의 끝 l에서 버퍼 의 포인터 가 0에 도달 했는지 확인하고 끊으면 스트림을 원래 루프로 다시 재설정합니다 [. 중첩 [루프에 필요합니다 .
snmcdonald

1
네. 나는 그렇게 생각했다. 루프에서 처음 입력 할 때 포인터 값을 확인하지 말고 현재 포인터 값을 확인해야합니다. 문제의 시험을 확인하십시오. 프로그램이 중단됩니다.
Alexandru

1
당신은 대체 할 수 있습니다 break;elsereturn;.
Alexandru

3
나는 당신이 바꿀 수 있다고 생각 (c==62)?a:b과 함께 (c-62)?b:a.
Alexandru

9

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

나는 eval을 사용하지 않고 주사를 맞았지만 결국 그것을 사용해야했습니다.

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

모든 명령이 작동합니다. 변수 변수가 많이 남용되고 경고가 발생합니다. 그러나 php.ini를 squelch warnings (또는 파이프 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

윈도우 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) 문자열로 더 잘 캐스팅하면 두 개의 괄호가 제거됩니다.
  • 2011-02-13 22:42 (204)에 대한 인수 뒤에 공백이 필요하지 않습니다 Write-Host.

8

C, 333 자

이것은 나의 첫번째 BF 통역사이고 내가 실제로 디버깅해야하는 첫번째 골프이다.

Mac OS X / GCC에서 소수 생성기를 실행하지만 #include<string.h>암시 적 정의가 strchr다른 플랫폼에서 작동하지 않는 경우 추가 문자가 19 자 이상 필요 합니다. 또한 가정합니다 O_RDONLY == 0. 그 외에도 3 문자 저장을 int선언 M하지 않으면 C99와 호환되지 않는 것 같습니다. 세 번째와 같은 *에서 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하고 함수 테이블 대신 대신 문자를 사용하는 것이 더 나쁠 것입니다. 나는 숫자 333과 테이블 : v)를 좋아한다.
Potatoswatter

아 맞다 나는 정말로 그것을 알고 있어야했다. E-notation은 부동 소수점 상수를 생성하는 반면 선언에는 정수가 필요합니다. BTW, 이것은 부정 행위 일 수 있지만 Urban Mü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 reverser , Hello World .

설명

STDIN의 첫 번째 줄에서 코드를 가져와 그 아래의 모든 줄에서 입력합니다.

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

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

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

그 마법 목록은 어때?

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

결과 목록은 다음과 같습니다.

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

우리의 미리보기 생성 +>대한 것들 -<, 단순히 (CJam의 "증가")을 마우스 오른쪽 괄호로 (CJam의 "감소") 왼쪽 괄호을 변경하여합니다.


최단 답변 및 최대 수상자
Jack Giffin

7

F # : 489 자

다음 프로그램은 '['/ ']'명령으로 이동하지 않지만 다음 일치하는 토큰에 대한 소스 코드를 스캔합니다. 물론 이것은 느리게 만들지 만 여전히 100 미만의 소수를 찾을 수 있습니다. F # 정수 유형은 오버플로되지 않고 랩됩니다.

짧은 버전은 다음과 같습니다.

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

불쾌한 점은 primes.bf 프로그램이 Windows 줄 바꿈에 질식한다는 것입니다. 그것을 실행하려면 입력 번호를 UNIX 형식의 텍스트 문서에 저장하고 파이프로 프로그램에 공급해야했습니다.

interpret.exe prime.bf < number.txt

편집 : Alt + 010을 입력 한 다음 Enter 키를 누르면 Windows cmd.exe 에서도 작동합니다.

더 긴 버전은 다음과 같습니다.

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

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

Enter 키를 누르지 않고 Ctrl + J :-)를 입력하여 문제를 해결했습니다.
Joey

Ctrl + J는 작동하지 않지만 Alt + 010을 입력하고 Enter를 입력하십시오.
cfern

7

델파이 397 개 382 378 371 366 364 328 문자

이 델파이를 먹어라!

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에서 멈추지 않습니다 ... CRLF OS에서 실행할 때 다른 제출 에서도이 문제가 발생합니까?


와! 나는 델파이와 함께 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 프로그램이 포함되어 있으며 두 번째 인수는 테이프의 크기를 결정합니다.


1
-D"q(a,b)"="*c-a||(b);"옵션을 계산하기 위해 카운트에 23자를 추가해야한다고 생각합니다. (적어도 제한된 이해로) 코드 축소에 도움이되는 것 같습니다.
Gareth

옵션은 게시 된 텍스트에 포함되어 있습니다. 그 이유는 긴 단어 define와 줄 바꿈 을 피하는 것이지만 실제로는 정결하지 않다고 생각합니다. 어쨌든 따옴표, 의견 및 gcc -D나는 이점을 전혀 보지 못합니다.
Potatoswatter

5

C, 267

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

./a.out primes.bf로 실행

언 골프 버전 :

#define J break;case

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

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

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

5

파이썬 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

소수 계산기를 잘 실행합니다.

알렉산드 루가 비슷한 점이 있습니다. 어쨌든 mny 답변을 게시 할 것입니다. 왜냐하면 새로운 아이디어가 있다고 생각하기 때문입니다.


5

C (gcc) Linux x86_64, 884621525 487 439 383358354 바이트

*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. 버퍼가 너무 작습니다. 프로그램 크기도 너무 작습니다.
Alexandru

나는 오타를 고쳤다. 프로그램 규모 란 무엇입니까? 최대 파일 크기를 의미하는 경우 처리 할 최소값을 지정하지 않았습니다.
jtjacques

4

루아, 285

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

다소 읽기 쉬운 버전 :

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

완벽하게 작동

Lua, 478,로드 스트링 없음

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

읽을 수있는 버전 :

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

4

Brainfuck, 948 바이트

글쎄, 그것은 시간이 걸렸습니다. 나는 Brainfuck 자체 통역사를 골랐다 .

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

4

리콜 , 594 바이트

간단히 말하면, Recall은 고전적인 의미에서 산술 연산자가 없으며 비트 연산 만 있습니다. "하나만 추가"할 수는 없습니다. 리콜도 스택 기반입니다.

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 프로그램이 실행됩니다. 하나의 명령 행 인수, 실행할 프로그램의 파일 이름을 허용합니다.

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) , 273268 바이트

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

온라인으로 사용해보십시오!

ceilingcat 덕분에 -5

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.