Brainfuck을 축소


22

다음 규칙에 따라 Brainfuck 코드 를 축소 해야합니다.

  • 중 하나가 아닌 것을 제거하십시오 +-><[].,.
  • 연속 +또는 -문자 그룹에 대해 +s와 -s 의 양이 같으면 제거하십시오.
  • 위와 동일하지만 >및을 사용하십시오 <.
  • +-><아무 것도하지 않으면 일련의 문자를 제거하십시오 . 예를 들어을 제거해야합니다 +>-<->+<. (이것은 구현하기가 가장 까다 롭고 어려운 방법 일 수 있습니다.)와 같은 잘못된 긍정을 얻지 마십시오 +>-<+>-<. 제거해서는 안됩니다.

테스트 사례 :

입력

++++++[->++++++<]>.   prints a $
[-]<                  resets tape
>,[>,]<[.<]           reverses NUL terminated input string
++-->><<              does nothing

산출

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

입력

Should disappear: ++>>+<+++<->-->-<<->-<
Should disappear: +++>-<--->+<
Should stay: +++>-<+>---<

산출

+++>-<+>---<

stdin / stdout, 함수 등 원하는대로 입력 및 출력을 수락 할 수 있지만 입력이 하드 코딩되지 않을 수 있습니다.

이것은 이므로 문자 수에서 가장 짧은 코드가 이깁니다.


4
나는 이것이 오래된 도전이라는 것을 알고 있지만 테스트 사례는 부적절합니다. ++>>++<<--출력해야하며 >>++<<다루지 않았습니다. 더 많은 테스트 사례를 추가하십시오.
mbomb007

@ mbomb007 마지막 테스트 사례를 조사 했 +++>-<+>---<습니까? 불필요한 포인터 이동을 피하기 위해 단축 할 수 있지만 예상되는 출력은 변경되지 않습니다. 질문과 답변을 모두 살펴본 결과, Doorknob은 사양이 느슨해지면서 시원함을 알게되었습니다. 우리는 무 조작 연속 제거합니다 +-><명시 적으로 언급 한 바와 같이 시퀀스를, 그 이상으로 당신의 예에서와 같이 별도의 파일 축소를 할 허용된다 ++>>++<<--, 그들은 예를 들어 코드의 기능을 변경하지 않는 한 우리는 또한 긴으로 재 배열을 만들 수 있습니다 >+<++>+<.
Mitch Schwartz

@MitchSchwartz "의 제거 순서의 + -.> <그들이 아무것도하지 않는 경우 문자 예를 들어, 당신은 제거해야합니다 +>-<->+<. (.이 구현하는 까다로운하고 어려운 일 수 있음)와 같은, 당신이 어떤 잘못된 반응하지 않도록주의하십시오 +>-<+>-<, "제거해서는 안됩니다." -막연하다
mbomb007

@ mbomb007 두 번째와 세 번째 글 머리 기호는 네 번째 글 머리 기호에 포함되어 있기 때문에 중복되고 불필요합니다. 그래서 무엇? 멋진 일입니다. 내 의견은 건설적이면서도 명확하게 설명하고 공격하지 않았습니다. 내가 의도 한대로 사용하거나 어떻게 다르게 말했는지 알려주세요. 내가 쓴 것을 실제로 다루지 않았기 때문입니다. 실제로 건설적이지 않고 자신을 방어하려는 것처럼 보입니다. 어떤 방법으로 모호합니까? 어떻게 다시 쓰시겠습니까? 질문을 편집 하시겠습니까? Doorknob에 문의 하시겠습니까?
Mitch Schwartz

1
아, 그래서 연속적인 시퀀스 만 제거하면 되나요?
mbomb007

답변:


10

반란군-104

_/^_$/$</([^][<>.,+-]|\+-|-\+|<>|><)//((?<X>(<|>))+[+-]+(?!\2)(?<-X><|>)+(?(X)(?!)))([+-]+)/$3$1/.+/$>$&

용법:

입력 : stdin에서 한 줄을 읽습니다.

출력 : 한 줄을 stdout에 인쇄합니다.

예외 * :

  • 입력 _하면 아무 것도 출력하지 않고 다른 행을 읽고 사용합니다.
  • 두 번째 테스트는 ++++>----<대신에 출력 됩니다 +++>-<+>---<. 그러나 괜찮습니다. ;)
  • >-<+등으로 교체됩니다 +>-<.

스포일러 :

변칙 # 3을 구현하면 사소한 일이됩니다.

* 버그가 아니라 기능입니다!


"그것은 버그가 아닙니다."+1!
Rohan Jhunjhunwala

36

Brainfuck, 579 바이트

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

서식 및 일부 주석 :

,
[
  <<+>> >>+<<
  [
    [<+> >+<-]
    ++++++[>-------<-]
    >-
    [
      not plus
      -
      [
        not comma
        -
        [
          not minus
          -
          [
            not period
            --------------
            [
              not less than
              --
              [
                not greater than
                <+++++[>------<-]>+
                [
                  not open bracket
                  --
                  [
                    not close bracket
                    <<[-]>>-
                  ]
                ]
                <
              ]
              >
              [
                greater than
                >>-<<
                <<<[-]<[<]<<<[<]
                >>>>>>>>[<]
                <-[+>]
                +[->+]
                >>>>+>[<-]
                <[>+<-<]
                >
              ]
              <
            ]
            >
            [
              less than
              <<<[-]-[<]
              >>>> >>>>>>>[<]
              <<<<<<[<]
              <-[+>]
              +[-<+]
              <<<+<[>-<<<]
              >[-<+<]
            ]
          ]
          <
        ]
        >
        [
          minus
          +>[-<]
          <[<<]
          <[-]>>
        ]
      ]
      <
    ]
    +>
    [
      plus
      -[<-]
      <[>+>+<<-<]
      <[-]>+>
    ]
    <<
    [
      comma or period or bracket
      >-
    ]
    >[,>]
    <
  ]
  comma or period or bracket or eof
  <+<
  [
    start and end same cell
    >
  ]
  >
  [
    >>>
    [
      <<<<[-<]<<<
    ]
    >>>+>>>>
    [
      start right of end
      <<<<->>>>
      [>>>[-<]>>>>]
    ]
  ]
  >
  [
    <<<
    [
      <+[-->>]
    ]
    >[-[.[-]]]
    >[<]
    >
    [
      <<++++++[>+++++++<-]>+>>
      [<<.>>-]
      <<++>-[<.>-]
      +++[<+++++>-]
      +<<<<< <+>
      [
        <<
        [
          go left
          >->>>>>.
          [[-]<<<<]
          <<<+>>>
        ]
        >
        [
          toggle left right
          ->->>>>[-]
        ]
      ]
      <
      [
        toggle right left
        ->+[>>>>>]>>[<]
        <<<<<<<<
        [
          [-]<
        ]
        >
        [
          go right
          ++.[-]
          >>>>>>>
        ]
        <
      ]
    ]
    >>
  ]
  <[>>>>>>>]
  +[-<<<<<[-]<<]
  ,
]

이것은 Keith Randall의 솔루션과 동일한 접근법을 사용하여 +-<>시뮬레이션에 의해 모든 연속 시퀀스를 최적으로 축소합니다 . 예를 들어, +++>-<+>---<++++>----<되고 >+<+<<+>+<->>>>됩니다 +<+>>+>.

온라인으로 사용해보십시오. (시뮬레이션 된 셀의 절대 값이 256에 가까워지면 오버플로 문제가 발생합니다.)

전반적인 구조는

while not EOF:
  while not EOF and next char not in ",.[]":
    process char
  print minified sequence (followed by the char in ",.[]" if applicable)

테이프는 7 셀 노드로 나뉩니다. 내부 루프의 시작 부분에서 메모리 레이아웃은

0 s 0 c 0 a b

여기서 sstart 셀의 부울 플래그이고 c현재 문자이며 a시뮬레이션 된 셀 값의 음수 부분 (1을 더한 값)이며 b시뮬레이션 된 셀 값의 양수 부분입니다.

축소 된 시퀀스가 ​​인쇄 될 때 메모리 레이아웃은

d n e 0 0 a b

여기서,는 d방향에 대한 부울 플래그이다, ab전과이다 (하나의 인쇄 / 제로되어 있지만), 및 ne엔드 노드에 대해서만 제로이고; n노드를 본 횟수와 관련이 e있으며 내부 루프를 중단 한 char 값 (1을 더한 값)입니다.

원래 노드 당 추가 정보를 추적하는 것을 고려했습니다. 가장 왼쪽 및 가장 오른쪽 노드는 부울 플래그이며 시작 및 끝 노드와 관련된 노드의 위치입니다. 그러나 필요할 때 인접한 셀을보고 시작 노드를 찾기 위해 왼쪽 및 오른쪽 스캔을 수행하여이를 피할 수 있습니다.

축소 된 시퀀스를 인쇄하고 시뮬레이션 된 포인터를 이동하는 방법을 결정할 때 일반적인 접근 방식을 취할 수 있습니다. 시작 노드와 끝 노드가 동일한 경우 임의의 방향으로 끝 노드에서 멀리 이동하여 가장 왼쪽과 오른쪽에서 돌아서십시오. 시작 노드와 종료 노드가 동일한 경우 3 회, 그렇지 않으면 2입니다.


2
출처 : brainfuck. 대상 : brainfuck. +1
Outgolfer Erik


1
나는 이것이 약간의 관심을 끌 수 있도록하고 하루 이틀에 현상금을 수여합니다
lirtosiast

1
@MitchSchwartz 코드와 코드를 테스트 했습니까? 실제로 단축시킬 수 있습니다! #meta
WallyWest

1
@WallyWest (7 바이트를 절약하는 것처럼 보입니다!) 퍼머 링크의 코드에는 줄 바꿈이 있습니다.
Dennis

7

파이썬, 404 자

이 코드는의 모든 하위 시퀀스를 완벽하게 최적화 +-<>합니다. 당신이 요구 한 것보다 조금 더 있지만, 거기에 있습니다.

M=lambda n:'+'*n+'-'*-n                                                           
def S(b):                                                                         
 s=p=0;t=[0];G,L='><'                                                             
 for c in b:                                                                      
  if'+'==c:t[p]+=1                                                                
  if'-'==c:t[p]-=1                                                                
  if G==c:p+=1;t+=[0]                                                             
  if L==c:s+=1;t=[0]+t                                                            
 if p<s:k=len(t)-1;t,p,s,G,L=t[::-1],k-p,k-s,L,G                                  
 r=[i for i,n in enumerate(t)if n]+[s,p];a,b=min(r),max(r);return(s-a)*L+''.join(M(n)+G for n in t[a:b])+M(t[b])+(b-p)*L                                           
s=b=''                                                                            
for c in raw_input():                                                             
 if c in'[].,':s+=S(b)+c;b=''                                                     
 else:b+=c                                                                        
print s+S(b) 

+-<>테이프 의 작업을 시뮬레이션하여 작동합니다 t. s테이프의 시작 위치 p이며 현재 위치입니다. 시뮬레이션 후에는 [a,b]작동해야 할 범위 를 파악하고 하나의 최적의 패스로 모든 +/-를 수행합니다.


1

CoffeeScript- 403 397

i=prompt().replace /[^\]\[,.+-><]/g,''
x=(c)->
 t={};p=n=0
 for d in c
  t[p]?=0;switch d
   when'+'then n=1;t[p]++;when'-'then n=1;t[p]--;when'<'then p--;when'>'then p++
 (n=0if v!=0)for k,v of t;n
s=e=0;((e++;(i=(i.substr 0,s)+i.substr e;e=s=0)if x (i.substr s,e-s).split "")while(i[e]||0)!in['[',']',0];e=++s)while s<=i.length
r=/(\+-|-\+|<>|><|^[<>]$)/g
i=i.replace r,'' while r.test i
alert i

데모 (여기에서 bit.ly 사용을 용서하십시오. 전체 URL이 마크 다운을 중단합니다)

압축되지 않은 버전 (디버그 코드 포함) :

console.clear()
input = """Should disappear: ++>>+<+++<->-->-<<->-<
Should disappear: +++>-<--->+<
Should stay: +++>-<+>---<"""

input = input.replace /[^\]\[,.+-><]/g, ''
console.log input

execute = (code) ->
  stack = {}
  item = 0
  console.log code
  nop = false
  for char in code
    switch char
      when '+' then nop = true; stack[item]?=0;stack[item]++
      when '-' then nop = true; stack[item]?=0;stack[item]--
      when '<' then item--
      when '>' then item++
  console.debug stack
  (nop = false if v != 0) for k,v of stack
  nop
start = 0
end = 0

while start <= input.length
 while input.charAt(end) not in [ '[', ']', '' ]
  end++
  if execute (input.substring start, end).split("")
    input = (input.substring 0, start) + input.substring end
    end = start = 0
    console.log input
 end = ++start
input = input.replace /(\+-|-\+|<>|><|^(<|>)$)/g, '' while /(\+-|-\+|<>|><)/.test input
console.log 'Result: ' + input

Coffeescript 데모를 게시하는 다른 방법은 JSFiddle을 사용하는 입니다. 왼쪽 여백에는 "언어"구성 창이 있으며 JS 대신 CoffeeScript를 사용할 수 있습니다.
피터 테일러

@PeterTaylor 감사합니다. JSFiddle에 대해 알고 있었지만 CoffeeScript를 사용할 수는 없습니다.
TimWolla

에 실패 >+.-<하여 빈 문자열을 변경하지 않고 생성합니다.
Mitch Schwartz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.