Python 2、157バイト
def f(s,o=0,d=0,D={}):T=s,o,d;x=D[T]=D[T]if T in D else~o and 0**o+sum(f(s[1:],cmp(c,"[")%-3-~o,d or cmp(c,s[0]))for c in"+,-.<>[]")if s else~d<0==o;return+x
まだかなりゴルファーに見えるが、今のところこれを投稿している。少しキャッシュを使用して再帰を使用します。迷惑なことに、D.get
キャッシュのために短絡しないので、そのように9バイトを保存することはできません...
マッピングは最初に長さを優先し、次に順序より辞書式順序を優先し"][><.-,+"
ます(以下の出力例を参照)。主なアイデアは、プレフィックスを比較することです。
変数o
は[
、現在のプレフィックスに対して開いている括弧の数を追跡しますd
が、変数は次の3つの値のいずれかを取ります。
d = 1
:現在の接頭辞は、辞書式に、よりも前ですs
。このプレフィックスと長さを持つすべてのプログラムを追加し<= s
、
d = -1
:現在の接頭辞は辞書的に後よりも後ですs
。このプレフィックスと長さを持つすべてのプログラムを追加します< s
。
d = 0
:現在のプレフィックスはのプレフィックスでs
あるため、d
後で1または-1に変更する可能性があります。
例えば、我々は持っている場合はs = "[-]"
、私たちの現在の接頭辞があるp = "+"
ことから、p
より後のs
辞書的に我々が始まるのプログラムを追加するだけ知ってp
いるとより厳密に短くなっていますs
。
より詳細な例を示すために、入力プログラムがあるとしますs = "-[]"
。最初の再帰的な展開はこれを行います:
(o == 0) # Adds a program shorter than s if it's valid
# For the first expansion, this is 1 for the empty program
+ f(s[1:], o=-1, d=1) # ']', o goes down by one due to closing bracket
+ f(s[1:], o=1, d=1) # '[', o goes up by one due to opening bracket
+ f(s[1:], o=0, d=1) # '>'
+ f(s[1:], o=0, d=1) # '<'
+ f(s[1:], o=0, d=1) # '.', d is set to 1 for this and the previous branches
# since they are lexicographically earlier than s's first char
+ f(s[1:], o=0, d=0) # '-', d is still 0 since this is equal to s's first char
+ f(s[1:], o=0, d=-1) # ',', d is set to -1 for this and the later branches
# since they are lexicographically later than s's first char
+ f(s[1:], o=0, d=-1) # '+'
注どのように我々は実際に再帰に接頭辞を使用していない-私たちはそれらを気にすべての変数介して取り込まれd
、o
そして縮小入力プログラムs
。上記の多くの繰り返しに気づくでしょう-これがキャッシュの出番であり、制限時間内に100文字のプログラムを処理できます。
ときはs
空で、私たちは見て(d>=0 and o==0)
1を返すかどうかを決定している、(それは/辞書的に早期に等しいだとプログラムが有効であるため、このプログラムをカウント)、または0(このプログラムはカウントされません)。
この接頭辞を持つプログラムはsよりも多くのsを持ち、したがって無効であるため、o < 0
すぐにを含む状況はを返します。0
]
[
最初の20の出力は次のとおりです。
1
> 2
< 3
. 4
- 5
, 6
+ 7
[] 8
>> 9
>< 10
>. 11
>- 12
>, 13
>+ 14
<> 15
<< 16
<. 17
<- 18
<, 19
<+ 20
@TheNumberOneの答えと同じHello Worldの例を使用します。
>>> f("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.")
3465145076881283052460228065290888888678172704871007535700516169748342312215139431629577335423L