पायथन 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
संकेत देने वाले तीन मानों में से एक लेता है:
d = 1
: वर्तमान उपसर्ग lexicographically पहले की तुलना में है s
। इस उपसर्ग और लंबाई के साथ सभी कार्यक्रम जोड़ें <= s
,
d = -1
: वर्तमान उपसर्ग lexicographically बाद की तुलना में है 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 (इस कार्यक्रम की गिनती न करें)।
किसी भी संतृप्ति के साथ o < 0
तुरंत रिटर्न 0
, क्योंकि इस उपसर्ग के साथ किसी भी कार्यक्रम की ]
तुलना में अधिक एस है [
, और इस प्रकार अमान्य हैं।
पहले 20 आउटपुट हैं:
1
> 2
< 3
. 4
- 5
, 6
+ 7
[] 8
>> 9
>< 10
>. 11
>- 12
>, 13
>+ 14
<> 15
<< 16
<. 17
<- 18
<, 19
<+ 20
@NumberOne के उत्तर के रूप में उसी हैलो वर्ल्ड उदाहरण का उपयोग करना:
>>> f("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.")
3465145076881283052460228065290888888678172704871007535700516169748342312215139431629577335423L