स्क्वेयरफाइंडर - नियमित टेट्रागनों का पता लगाना


27

विमान में खींची गई आयतों के एक समूह की कल्पना करें, पूर्णांक निर्देशांक और उसके किनारों पर अक्षों के समानांतर प्रत्येक आयत:

यहाँ छवि विवरण दर्ज करें

आयतें विमान को कई अलग-अलग क्षेत्रों में विभाजित करती हैं, नीचे लाल और नीले रंग में:

यहाँ छवि विवरण दर्ज करें

आपका लक्ष्य ऐसे क्षेत्रों की संख्या का पता लगाना है जो सही वर्ग हैं। उपरोक्त उदाहरण में, तीन हैं:

यहाँ छवि विवरण दर्ज करें

ध्यान दें कि बीच में बड़ा वर्ग नहीं गिना जाता है क्योंकि यह एक एकल क्षेत्र नहीं है, बल्कि इसके बजाय कई छोटे क्षेत्रों से बना है।

इनपुट

आप इस चुनौती के लिए एक समारोह या एक पूर्ण कार्यक्रम लिख सकते हैं।

समतल में आयतों को 4nपरिभाषित करने वाले इनपुट नॉनगेटिव पूर्णांक होंगे n। प्रत्येक आयत को दो विपरीत कोणों द्वारा दर्शाया जाता है, उदाहरण के 4 9 7 8लिए लंबवत विरोधों के साथ आयत का प्रतिनिधित्व करता है (4, 9)और (7, 8)। ध्यान दें कि इस आयत को 7 8 4 9या के रूप में भी दर्शाया जा सकता है 4 8 7 9

सटीक इनपुट प्रारूप लचीला है (जैसे अंतरिक्ष-पृथक स्ट्रिंग, अल्पविराम से अलग स्ट्रिंग, पूर्णांक का एकल सरणी, समन्वित ट्यूपल्स की सूची, और इसी तरह), लेकिन कृपया उचित रहें और अपने पोस्ट में अपने कोड को चलाने के तरीके का एक उदाहरण दें। आप इनपुट को पुनः व्यवस्थित नहीं कर सकते हैं।

सादगी के लिए, आप मान सकते हैं कि कोई भी दो किनारों को अतिव्यापी नहीं होगा - इसमें एक शीर्ष पर ओवरलैपिंग शामिल है। विशेष रूप से, इसका तात्पर्य यह है कि कोई भी दो आयतें किनारे-से-किनारे या कोने-से-कोने को छूने वाली नहीं होंगी, और आयतों में नॉनज़ेरो क्षेत्र होगा।

उत्पादन

आपके कार्यक्रम को एक एकल पूर्णांक को प्रिंट या वापस करना चाहिए, जो वर्ग क्षेत्रों की संख्या है।

स्कोरिंग

यह कोड गोल्फ है, इसलिए सबसे कम बाइट्स में कोड जीतता है।


परीक्षण के मामलों

इनपुट:

0 0 5 5
6 8 10 4
14 16 11 13
19 1 18 2

आउटपुट:

4

यह बस चार असमान वर्ग है:

यहाँ छवि विवरण दर्ज करें


इनपुट:

2 1 3 11
1 10 5 19
6 10 11 3
8 8 15 15
13 13 9 5
15 1 19 7
17 19 19 17

आउटपुट:

3

यह पद के प्रारंभ में उदाहरण परीक्षण का मामला है।


इनपुट:

0 9 15 12
6 3 18 15
9 6 12 20
13 4 17 8

आउटपुट:

7

यहाँ छवि विवरण दर्ज करें


इनपुट:

5 9 11 10
5 12 11 13
6 8 7 14
9 8 10 14
13 8 14 9
13 10 14 14

आउटपुट:

14

यहाँ छवि विवरण दर्ज करें


इनपुट:

0 99999 100000 0

आउटपुट:

0

यह सिर्फ एक बड़ी आयत है।


इनपुट:

0 99999 100000 0
2 1 142857 285714

आउटपुट:

1

दो बड़े आयत जो ओवरलैप करते हैं।

जवाबों:


9

SQL (POSTGIS), 286 269 261 240 226 218 216

यह PostGreSQL के लिए PostGIS एक्सटेंशन के लिए एक क्वेरी है। मैंने कुल में इनपुट मानों की गिनती नहीं की है।

SELECT SUM(1)FROM(SELECT(ST_Dump(ST_Polygonize(g))).geom d FROM(SELECT ST_Union(ST_Boundary(ST_MakeEnvelope(a,b,c,d)))g FROM(VALUES
-- Coordinate input
(2, 1, 3, 11)
,(1, 10, 5, 19)
,(6, 10, 11, 3)
,(8, 8, 15, 15)
,(13, 13, 9, 5)
,(15, 1, 19, 7)
,(17, 19, 19, 17)
)i(a,b,c,d))i)a WHERE(ST_XMax(d)-ST_XMin(d))^2+(ST_YMax(d)-ST_YMin(d))^2=ST_Area(d)*2

व्याख्या

क्वेरी प्रत्येक समन्वय जोड़ी के लिए ज्यामिति का निर्माण करती है। बाहरी रिंगों को लाइनों को ठीक से नोड करने के लिए एकजुट करता है। परिणामों को बहुभुज में बदल देता है और ऊंचाई के खिलाफ चौड़ाई का परीक्षण करता है और प्रत्येक पक्ष के योग के विपरीत क्षेत्र दोगुना हो जाता है।

यह PostGreSQL डेटाबेस पर PostGreSQL डेटाबेस के साथ एक स्टैंडअलोन क्वेरी के रूप में चलेगा।

संपादित करें कुछ और मिला।


1
... और हास्केल
ऑप्टिमाइज़र

@ दत्तक मुझे शक है कि यह पिछले होगा :)
मिकट

@ मिक्की यह एक स्वस्थ प्रतियोगिता में बदल गया है। :)
ज़गारब

@ ज़र्ब यह थोड़ा सा है :-) लेकिन मुझे नहीं लगता कि मुझे कुछ और मिला।
मिकटी

13

अजगर 2, 480 436 386 352 बाइट्स

exec u"""s=sorted;H=[];V=[]
FRIinput():
 S=2*map(s,zip(*R))
 FiI0,1,2,3:
    c=S[i][i/2];a,b=S[~i]
    FeIs(H):
     C,(A,B)=e
     if a<C<b&A<c<B:e[:]=C,(A,c);H+=[C,(c,B)],;V+=[c,(a,C)],;a=C
    V+=[c,(a,b)],;H,V=V,H
print sum(a==A==(d,D)&c==C==(b,B)&B-b==D-d&1-any(d<X[0]<D&b<y<B Fy,XIH)Fb,aIH FB,AIH Fd,cIV FD,CIV)""".translate({70:u"for ",73:u" in ",38:u" and "})

प्रारूप में STDIN के माध्यम से समन्वित जोड़े की सूची लेता है:

[  [(x, y), (x, y)],  [(x, y), (x, y)],  ...  ]

और परिणाम को STDOUT में प्रिंट करता है।


स्ट्रिंग प्रतिस्थापन के बाद वास्तविक कार्यक्रम है:

s=sorted;H=[];V=[]
for R in input():
 S=2*map(s,zip(*R))
 for i in 0,1,2,3:
    c=S[i][i/2];a,b=S[~i]
    for e in s(H):
     C,(A,B)=e
     if a<C<b and A<c<B:e[:]=C,(A,c);H+=[C,(c,B)],;V+=[c,(a,C)],;a=C
    V+=[c,(a,b)],;H,V=V,H
print sum(a==A==(d,D) and c==C==(b,B) and B-b==D-d and 1-any(d<X[0]<D and b<y<B for y,X in H)for b,a in H for B,A in H for d,c in V for D,C in V)

व्याख्या

जटिल पॉलीगॉन के साथ फ़िडलिंग के बजाय, यह कार्यक्रम सरल लाइन सेगमेंट से संबंधित है। प्रत्येक इनपुट आयत के लिए, हम इसके प्रत्येक चार किनारों को व्यक्तिगत रूप से एक सामूहिक खंड सूची में जोड़ते हैं। सूची में एक खंड जोड़ना इस प्रकार है: हम नए खंड के साथ चौराहे के लिए मौजूदा खंडों में से प्रत्येक का परीक्षण करते हैं; यदि हमें एक चौराहा मिल जाता है, तो हम दोनों खंडों को चौराहे के बिंदु पर विभाजित करते हैं और जारी रखते हैं। चीजों को आसान बनाने के लिए, हम वास्तव में दो अलग-अलग खंड सूची रखते हैं: एक क्षितिज एक और एक ऊर्ध्वाधर। चूंकि खंड ओवरलैप नहीं करते हैं, क्षैतिज खंड केवल ऊर्ध्वाधर खंडों को काट सकते हैं और इसके विपरीत। बेहतर अभी तक, इसका मतलब है कि सभी चौराहों (एक ही आयत के किनारों पर विचार नहीं) "उचित" हैं, अर्थात, हमारे पास टी-आकार के चौराहे नहीं हैं, इसलिए प्रत्येक खंड के "दोनों पक्ष" वास्तव में विभाजित हैं।

एक बार जब हमने खंड सूची (ओं) का निर्माण कर लिया है, तो हम वर्गों की गणना शुरू करते हैं। चार खंडों (विशेष रूप से, दो क्षैतिज खंडों और दो ऊर्ध्वाधर वाले) के प्रत्येक संयोजन के लिए, हम परीक्षण करते हैं कि क्या वे एक वर्ग बनाते हैं। इसके अलावा, हम यह सत्यापित करते हैं कि कोई वर्टेक्स इस वर्ग के भीतर नहीं है (जो कि हो सकता है, उदाहरण के लिए, हमारे पास एक बड़ा वर्ग के अंदर एक छोटा वर्ग है।) इससे हमें वांछित मात्रा मिलती है। ध्यान दें कि भले ही कार्यक्रम प्रत्येक संयोजन का चार बार अलग-अलग आदेशों में परीक्षण करता है, खंड निर्देशांक का विशेष क्रम गारंटी देता है कि हम प्रत्येक वर्ग को केवल एक बार गिनते हैं।


1
मैं इस बात से बहुत प्रभावित हूं कि आपने इसे कितनी जल्दी हल किया और जिस तरह से आप समस्या के पास पहुंचे! लूप्स के लिए मुझे "निश्चित रूप से कुछ किया जा सकता है ..."
Sp3000

@ Sp3000 हाँ। मैं itertoolsछोरों के लिए उपयोग करने की कोशिश की , लेकिन यह लंबे समय तक समाप्त हो रहा है। मैं exec+ स्ट्रिंग प्रतिस्थापन के साथ कुछ बाइट्स शेव कर सकता हूं , लेकिन कुछ भी रोमांचक नहीं है।
एल डे

4

हास्केल, 276 266 250 237 225 222 217 बाइट्स

यह छोटा होता जा रहा है ... और अधिक अस्पष्ट।

(x#i)l=mapM id[[min x i..max x i-1],l]
(y!j)l f=and[p l==p(f[y,j])|p<-map elem$f[y..j]]
s[h,v]=sum[1|[x,j]<-h,[y,i]<-v,x<i,i-x==j-y,(y!j)h$x#i,(x!i)v$y#j]
n=s.foldr(\(x,y,i,j)->zipWith(++)[x#i$[y,j],y#j$[x,i]])[[],[]]

n [(0,0,5,5),(6,8,10,4),(14,16,11,13),(19,1,18,2)]पहले टेस्ट केस के लिए मूल्यांकन करें । मुझे लगता है कि मैं हास्केल पर इस एल्गोरिथ्म को गोल करने की सीमा के करीब पहुंच रहा हूं।

यह फ़ंक्शन इतना धीमा है (कम से कम ओ (एन 3 ) जहां n इनपुट में सभी आयतों की कुल परिधि है) कि मैं पिछले दो परीक्षण मामलों पर इसका मूल्यांकन नहीं कर सकता। जब मैंने इसे अनुकूलन के साथ संकलित किया और इसे [(0,249,250,0),(2,1,357,714)]अंतिम परीक्षण के 400-बार सिकुड़ने वाले संस्करण पर चलाया , तो यह 12 सेकंड में समाप्त हो गया। इसके आधार पर, वास्तविक परीक्षण मामला लगभग 25 वर्षों में समाप्त हो जाएगा।

स्पष्टीकरण (आंशिक, मैं समय होने पर इसका विस्तार करूंगा)

हम पहले दो सूचियों का निर्माण करते हैं hऔर vइस प्रकार हैं। इनपुट में प्रत्येक आयत के लिए, हम इसकी सीमा को लंबाई के सेगमेंट में विभाजित करते हैं। 1. क्षैतिज सेगमेंट के वेस्ट hएंड पॉइंट्स को स्टोर किया जाता है , और वर्टिकल सेगमेंट के साउथ एंडपॉइंट्स को लंबाई की vसूचियों [x,y]के रूप में vजमा किया जाता है । 2. निर्देशांक एक उलट में संग्रहीत होते हैं। [y,x]गोल्फ कारणों से फार्म । फिर हम बस दोनों सूचियों पर लूप करते हैं और क्षैतिज किनारे [x,j]और ऊर्ध्वाधर किनारे की खोज करते हैं, [i,y]जैसे ( x < iऔर i-x == j-yवे एक वर्ग के उत्तर-पश्चिम और दक्षिण-पूर्वी कोने) हैं, और जांचें कि वर्ग की सीमाएं सही सूचियों में हैं hऔर v, जबकि आंतरिक निर्देशांक नहीं हैं। खोज के सकारात्मक उदाहरणों की संख्या आउटपुट है।


अच्छा हुआ, मुझे लगता है कि मुझे अब
जीतना होगा

@ मिक्की यह एक सप्ताह हो गया है इसलिए मैंने अब के लिए ज़र्गब के उत्तर को स्वीकार कर लिया है, लेकिन यदि आप इसे हरा देते हैं तो बाद में चेक मार्क हट जाएगा! ईमानदारी से, मैं बहुत प्रभावित हूँ कि आप दोनों कितनी दूर जाने में कामयाब रहे
Sp3000

@Zgarb अच्छी तरह से जीत के हकदार थे :-)
मिक्यट

@ Sp3000 एक छोटी सी चुनौती के लिए धन्यवाद।
मिक्यट

@ Sp3000 धन्यवाद! मुझे इसमें बहुत मज़ा आया।
ज़गरब
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.