Python 2, 157 byte
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
Masih terlihat cukup golf, tapi saya memposting ini untuk saat ini. Ini menggunakan rekursi dengan sedikit caching. Yang menjengkelkan, D.get
tidak ada hubungan pendek untuk caching, jadi saya tidak bisa menyimpan 9 byte seperti itu ...
Pemetaan memprioritaskan panjang pertama, kemudian urutan leksikografis atas pemesanan "][><.-,+"
(lihat contoh output di bawah). Gagasan utamanya adalah membandingkan awalan.
Variabel o
melacak jumlah [
kurung masih terbuka untuk awalan saat ini, sementara variabel d
mengambil salah satu dari tiga nilai yang menunjukkan:
d = 1
: Awalan saat ini secara leksikografis lebih awal dari s
. Tambahkan semua program dengan awalan dan panjang ini <= s
,
d = -1
: Awalan saat ini secara leksikografis lebih lambat dari s
. Tambahkan semua program dengan awalan dan panjang ini < s
.
d = 0
: Awalan saat ini adalah awalan dari s
, jadi kami mungkin berubah d
ke 1 atau -1 nanti.
Sebagai contoh, jika kita memiliki s = "[-]"
dan awalan kita saat ini p = "+"
, karena p
lebih lambat dari pada s
leksikografis kita hanya tahu untuk menambahkan program yang dimulai dengan p
yang lebih singkat dari itu s
.
Untuk memberikan contoh yang lebih rinci, anggaplah kita memiliki program input s = "-[]"
. Ekspansi rekursif pertama melakukan ini:
(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) # '+'
Perhatikan bagaimana kita sebenarnya tidak menggunakan awalan dalam rekursi - semua yang kita pedulikan adalah ditangkap melalui variabel d
, o
dan program input menyusut s
. Anda akan melihat banyak pengulangan di atas - di sinilah caching masuk, memungkinkan kami untuk memproses program 100-ar dengan baik dalam batas waktu.
Ketika s
kosong, kita melihat (d>=0 and o==0)
, yang memutuskan apakah akan mengembalikan 1 (hitung program ini karena secara leksikografis awal / sama dan program itu valid), atau 0 (jangan hitung program ini).
Setiap situasi dengan o < 0
segera kembali 0
, karena setiap program dengan awalan ini memiliki lebih ]
dari [
, dan karenanya tidak valid.
20 output pertama adalah:
1
> 2
< 3
. 4
- 5
, 6
+ 7
[] 8
>> 9
>< 10
>. 11
>- 12
>, 13
>+ 14
<> 15
<< 16
<. 17
<- 18
<, 19
<+ 20
Menggunakan contoh Hello World yang sama dengan jawaban @ TheNumberOne:
>>> f("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.")
3465145076881283052460228065290888888678172704871007535700516169748342312215139431629577335423L