हास्केल , 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]]यह सुनिश्चित करने के लिए एक