हास्केल , 228 227 225 224 बाइट्स
import Data.List
z=zipWith
a!b=div(max(a*a)(a*b))a
l x=z(!)(z(!)x(0:x))$tail x++[0]
s=(\x->length.($x).filter<$>[(>0),(<0)]).nub.(>>=id).(until=<<((==)=<<))((.)>>=id$transpose.map l).z(\i->z(\j x->2^i*j*(2*x-1))[1,3..])[1..]
इसे ऑनलाइन आज़माएं!
स्पष्टीकरण:
इस समाधान के लिए विचार निम्नानुसार है: प्रत्येक सेल में अद्वितीय मूल्यों के साथ मैट्रिक्स को आरम्भ करें, के लिए सकारात्मक 1
और नकारात्मक 0
। फिर बार-बार प्रत्येक सेल की अपने पड़ोसियों से तुलना करें और, यदि पड़ोसी के पास एक ही चिन्ह है लेकिन एक बड़ा निरपेक्ष मान वाला नंबर है, तो सेल के नंबर को पड़ोसी के नंबर से बदल दें। एक बार जब यह निश्चित बिंदु पर आ जाता है, तो 1
क्षेत्रों की संख्या के लिए अलग-अलग सकारात्मक संख्याओं की संख्या और क्षेत्रों की संख्या के लिए अलग-अलग ऋणात्मक संख्याओं की गणना करें 0
।
कोड में:
s=(\x->length.($x).filter<$>[(>0),(<0)]).nub.(>>=id).(until=<<((==)=<<))((.)>>=id$transpose.map l).z(\i->z(\j x->2^i*j*(2*x-1))[1,3..])[1..]
प्रीप्रोसेसिंग (कोशिकाओं को संख्या निर्दिष्ट करना), पुनरावृत्ति और पोस्टप्रोसेसिंग (कोशिकाओं की गिनती) में विभाजित किया जा सकता है
preprocessing
प्रीप्रोसेसिंग हिस्सा फ़ंक्शन है
z(\i->z(\j x->2^i*j*(2*x-1))[1,3..])[1..]
जो कुछ बाइट्स को शेव करने के z
लिए संक्षिप्त नाम के रूप में उपयोग करता है zipWith
। हम यहाँ क्या करते हैं पंक्तियों में पूर्णांक सूचकांकों और स्तंभों में विषम पूर्णांक सूचक के साथ दो आयामी सरणी को ज़िप करें। हम ऐसा करते हैं क्योंकि हम (i,j)
सूत्र का उपयोग करके पूर्णांक की एक जोड़ी से एक अद्वितीय पूर्णांक बना सकते हैं (2^i)*(2j+1)
। यदि हम केवल विषम पूर्णांक उत्पन्न करते हैं j
, तो हम 2*j+1
तीन बाइट्स की बचत करते हुए , गणना करना छोड़ सकते हैं ।
अद्वितीय संख्या के साथ, अब हमें केवल मैट्रिक्स में मूल्य के आधार पर एक संकेत में गुणा करना होगा, जो कि प्राप्त होता है 2*x-1
यात्रा
द्वारा पुनरावृति किया जाता है
(until=<<((==)=<<))((.)>>=id$transpose.map l)
चूंकि इनपुट सूची की एक सूची के रूप में है, इसलिए हम प्रत्येक पंक्ति पर पड़ोसी की तुलना करते हैं, मैट्रिक्स को स्थानांतरित करते हैं, प्रत्येक पंक्ति पर फिर से तुलना करते हैं (जो कि संक्रमण के कारण कॉलम पहले था) और फिर से प्रस्ताव करते हैं। इन चरणों में से एक को पूरा करने वाला कोड है
((.)>>=id$transpose.map l)
जहां l
तुलना समारोह (नीचे विवरण) और है transpose.map l
प्रदर्शन तुलना और स्थानांतरण चरणों में से एक आधा। ऑपरेटर पूर्ववर्ती नियमों के कारण इस मामले में (.)>>=id
दो बार अपना तर्क प्रस्तुत करता है, \f -> f.f
और इस मामले में एक बाइट से छोटा होता है।
l
के रूप में ऊपर पंक्ति में परिभाषित किया गया है l x=z(!)(z(!)x(0:x))$tail x++[0]
। यह कोड (!)
प्रत्येक सेल पर पहले बाएं पड़ोसी के साथ तुलना ऑपरेटर (नीचे देखें) करता है, और फिर अपने दाएं पड़ोसी के साथ, सूची x
को दाईं ओर स्थानांतरित सूची 0:x
और बाएं स्थानांतरित सूची के साथ ज़िप करके tail x++[0]
। शिफ्ट की गई सूचियों को पैड करने के लिए हम शून्य का उपयोग करते हैं, क्योंकि वे प्रीप्रोसेस मैट्रिक्स में कभी नहीं हो सकते हैं।
a!b
इस के रूप में ऊपर पंक्ति में परिभाषित किया गया है a!b=div(max(a*a)(a*b))a
। हम यहाँ क्या करना चाहते हैं निम्नलिखित मामले भेद है:
- यदि
sgn(a) = -sgn(b)
, हमारे पास मैट्रिक्स में दो विरोधी क्षेत्र हैं और उन्हें एकजुट करने की इच्छा नहीं है, तो a
अपरिवर्तित रहता है
- यदि
sgn(b) = 0
, हमारे पास कोने का मामला है जहां b
पेडिंग है और इसलिए a
अपरिवर्तित रहता है
- यदि
sgn(a) = sgn(b)
, हम दो क्षेत्रों को एकजुट करना चाहते हैं और एक को बड़े निरपेक्ष मूल्य (सुविधा के लिए) के साथ लेना चाहते हैं।
ध्यान दें कि sgn(a)
कभी नहीं हो सकता 0
। हम इसे दिए गए सूत्र के साथ पूरा करते हैं। यदि संकेत a
और b
भिन्न होते हैं, a*b
तो शून्य से कम या बराबर होता है, जबकि a*a
हमेशा शून्य से अधिक होता है, इसलिए हम इसे अधिकतम के रूप में चुनते हैं और a
वापस पाने के लिए विभाजित करते हैं a
। अन्यथा, max(a*a)(a*b)
है abs(a)*max(abs(a),(abs(b))
, और इसके द्वारा विभाजित करके a
, हम प्राप्त करते हैं sgn(a)*max(abs(a),abs(b))
, जो कि बड़े निरपेक्ष मान के साथ संख्या है।
फ़ंक्शन को पुनरावृत्त करने के लिए ((.)>>=id$transpose.map l)
जब तक यह एक निश्चित बिंदु तक नहीं पहुंचता, हम उपयोग करते हैं (until=<<((==)=<<))
, जो इस स्टैकओवरफ़्लो उत्तर से लिया जाता है ।
प्रोसेसिंग के बाद
पोस्टप्रोसेसिंग के लिए, हम भाग का उपयोग करते हैं
(\x->length.($x).filter<$>[(>0),(<0)]).nub.(>>=id)
जो सिर्फ चरणों का एक संग्रह है।
(>>=id)
सूचियों की सूची को एकल सूची में
विभाजित करता है nub
, युगल से छुटकारा दिलाता है,
(\x->length.($x).filter<$>[(>0),(<0)])
सूची को सूची में जोड़े में रखता है, सकारात्मक के लिए एक और नकारात्मक संख्या के लिए एक, और उनकी लंबाई की गणना करता है।
[[1,0];[0,1]]
यह सुनिश्चित करने के लिए एक