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最後のテストケースを調べました+++>-<+>---<か?不必要なポインターの移動を避けるために短縮できますが、予想される出力では変更されません。質問と回答の両方を見ることに基づいた私の理解は、ドアノブはクールであり、仕様がゆるく取られているということです。我々は、任意の無操作の連続除去する必要があります+-><明示的に指定される配列を、そしてそれを超えて、あなたの例のように余分により縮小を行うことは許されて++>>++<<--、そして我々はまた、長い間、彼らはコードの機能を変更しないようとして再編成を行うことができ、例えば>+<++>+<
ミッチシュワルツ

+の@MitchSchwartz「削除シーケンス- 。> <文字彼らは何もしない場合たとえば、あなたは削除する必要があります+>-<->+<(これは、実装するためのトリッキーかつ最も困難なものであってもよい。)のように、あなたが任意の偽陽性を得ることはありません確認します。+>-<+>-<、削除しないでください。」-これは一種のあいまいです
-mbomb007

@ mbomb007そして、2番目と3番目の箇条書きは冗長であり、4番目の箇条書きに含まれているため不要です。だから何?それはクールなタスクです。私のコメントは、あなたを攻撃するのではなく、建設的で明確にすることを目的としていました。それを私が意図した方法で取ってください、または私がそれを違うように言うべきだった方法を教えてください。あなたは本当に私が書いたことに対処しなかったからです。本当に建設的でなく自分を守ろうとしているようです。どのように曖昧に感じますか?どのように書き換えますか?質問を編集しますか?ドアノブに聞きたいですか?
ミッチシュワルツ

1
ああ、連続したシーケンスを削除するだけでいいのですか?
mbomb007

回答:


10

反乱-104

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

使用法:

入力:標準入力から1行読み取ります。

出力:1行を標準出力に出力します。

異常*:

  • 入力_すると、何も出力せずに、別の行が読み取られて使用されます。
  • 2番目のテストはの++++>----<代わりに出力します+++>-<+>---<。でも大丈夫ですよね?;)
  • >-<+などに置き換えられている+>-<など

スポイラー:

異常#3を実装すると、物事が非常に簡単になります。

*これはバグではなく、機能です!


「バグではなく機能です」+1!
ローハンジュンジュンワラ

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

ここで、sは開始セルのブールフラグc、現在の文字、aシミュレーションセル値のマイナス部分(プラス1)、およびbシミュレーションセル値のプラス部分です。

縮小されたシーケンスが印刷されるとき、メモリレイアウトは

d n e 0 0 a b

where dは、方向を表すブールフラグで、以前ab同じ(ただし、印刷するne1/0になります)であり、エンドノードではゼロ以外の値になります。nは、ノードが表示された回数に関連しe、内側のループを停止したcharの値(プラス1)です。

もともと、ノードごとの詳細情報を追跡することを検討しました。左端と右端のノードをブールフラグとして、ノードの開始ノードと終了ノードに対する位置。ただし、必要に応じて隣接するセルを調べ、開始ノードを見つけるために左右のスキャンを実行することで、これを回避できます。

縮小されたシーケンスを印刷し、シミュレートされたポインターを移動する方法を決定するとき、一般的なアプローチをとることができます:開始ノードと終了ノードが同じである場合は任意の方向に)終了ノードから離れることから始め、左端と右端で向きを変えますノード、および終了ノードが表示された回数に基づいて停止します。開始ノードと終了ノードが同じ場合は3回、そうでない場合は2。


2
ソース:brainfuck。ターゲット:brainfuck。+1
エリック・ザ・アウトゴルファー


1
これに少し注意を引き付け、
1〜2

1
@MitchSchwartzコードに対してコードをテストしたことがありますか?実際に短くすることができます!#meta
WallyWest

1
@WallyWest(7バイトを節約するようです!)パーマリンクのコードには改行があります。
デニス

7

Python、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) 

+-<>テープ上の操作をシミュレートすることで機能しますtsはテープの開始位置でpあり、現在の位置です。シミュレーション後、[a,b]操作が必要な範囲を把握し、すべての+/-を1つの最適なパスで実行します。


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

これは失敗し>+.-<、変更せずに空の文字列を生成します。
ミッチシュワルツ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.