हास्केल , 166 154 बाइट्स
(-12 बाइट्स लाईकोनी की बदौलत, (ज़िप और लिम्बड़ा के बजाय जिप और लिस्ट की समझ, पहली लाइन जनरेट करने का बेहतर तरीका))
i#n|let k!p=p:(k+1)![m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))|(l,m,r)<-zip3(1:p)p$tail p++[1]];x=1<$[2..2^n]=mapM(putStrLn.map("M "!!))$take(2^n)$1!(x++0:x)
इसे ऑनलाइन आज़माएं!
स्पष्टीकरण:
फ़ंक्शन पुनरावृत्ति के चरणों के बाद i#n
ऊंचाई के ASCII-त्रिकोण को खींचता है ।2^n
i
आंतरिक रूप से उपयोग की जाने वाली एन्कोडिंग रिक्त पदों को 1
और पूर्ण स्थिति के रूप में संलग्न करती है 0
। इसलिए त्रिभुज की पहली पंक्ति के रूप में एन्कोड किया गया है [1,1,1..0..1,1,1]
के साथ 2^n-1
शून्य के दोनों किनारों पर लोगों को। इस सूची का निर्माण करने के लिए, हम सूची के साथ शुरू करते हैं x=1<$[2..2^n]
, यानी [2..2^n]
हर चीज के साथ सूची 1
। फिर, हम पूरी सूची का निर्माण करते हैंx++0:x
ऑपरेटर k!p
(नीचे विस्तृत विवरण), एक लाइन इंडेक्स दिया गया k
और एक p
अनुवर्ती लाइनों की एक अनंत सूची उत्पन्न करता है p
। हम इसे 1
पूरे त्रिकोण को प्राप्त करने के लिए और ऊपर वर्णित प्रारंभिक रेखा के साथ लागू करते हैं , और उसके बाद केवल पहली 2^n
पंक्तियों को लेते हैं। फिर, हम बस प्रत्येक पंक्ति मुद्रित, जगह 1
जगह के साथ और 0
साथ M
(सूची पर पहुंचकर "M "
स्थान पर 0
या 1
)।
ऑपरेटर k!p
को निम्नानुसार परिभाषित किया गया है:
k!p=p:(k+1)![m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))|(l,m,r)<-zip3(1:p)p$tail p++[1]]
सबसे पहले, हम तीन संस्करण उत्पन्न करते हैं p
: 1:p
जो कि p
एक 1
पूर्वनिर्मित के साथ है , p
स्वयं और tail p++[1]
जो कि सब कुछ है लेकिन पहले तत्व के p
साथ एक 1
जोड़ा गया है। हम फिर इन तीन सूचियों को ज़िप करते हैं, हमें p
उनके बाएं और दाएं पड़ोसियों के साथ सभी तत्वों को प्रभावी रूप से देते हैं, जैसा कि (l,m,r)
। हम तब नई पंक्ति में संबंधित मान की गणना करने के लिए एक सूची समझ का उपयोग करते हैं:
m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))
इस अभिव्यक्ति को समझने के लिए, हमें यह समझने की जरूरत है कि विचार करने के लिए दो बुनियादी मामले हैं: या तो हम बस पिछली पंक्ति का विस्तार करते हैं, या हम उस बिंदु पर हैं जहां त्रिकोण में एक खाली स्थान शुरू होता है। पहले मामले में, हमारे पास एक भरा हुआ स्थान है यदि पड़ोस में कोई भी स्पॉट भरा हुआ है। इसकी गणना इस प्रकार की जा सकती है m*l*r
; यदि इन तीनों में से कोई भी शून्य है, तो नया मान शून्य है। दूसरा मामला थोड़ा पेचीदा है। यहां, हमें मूल रूप से एज डिटेक्शन की आवश्यकता है। निम्न तालिका नई पंक्ति में परिणामी मान के साथ आठ संभावित पड़ोस देती है:
000 001 010 011 100 101 110 111
1 1 1 0 1 1 0 1
इस तालिका को प्राप्त करने का एक सीधा सूत्र होगा 1-m*r*(1-l)-m*l*(1-r)
जो सरल हो जाता है m*(2*l*r-l-r)+1
। अब हमें इन दो मामलों के बीच चयन करने की आवश्यकता है, जहां हम लाइन नंबर का उपयोग करते हैं k
। यदि mod k (2^(n-i)) == 0
, हमें दूसरे मामले का उपयोग करना है, अन्यथा, हम पहले मामले का उपयोग करते हैं। 0^(mod k(2^n-i))
इसलिए शब्द यह है 0
कि अगर हमें पहले मामले का उपयोग करना है और 1
अगर हमें दूसरे मामले का उपयोग करना है। नतीजतन, हम उपयोग कर सकते हैं
m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))
कुल में - यदि हम पहले मामले का उपयोग करते हैं, तो हम बस प्राप्त m*l*r
करते हैं , जबकि दूसरे मामले में, एक अतिरिक्त शब्द जोड़ा जाता है, जो कि भव्य कुल देता है m*(2*l*r-l-r)+1
।