एक बहुभुज पर पक्षों की संख्या की गणना करें


18

एक बहुभुज पर पक्षों की संख्या की गणना करें

बहुभुज-साइड-गिनती रोबोट ने पहले किसी को बताए बिना दुनिया की यात्रा करने का फैसला किया है, लेकिन यह महत्वपूर्ण है कि बहुभुज की गिनती की प्रक्रिया बहुत लंबे समय तक नहीं रुकी है। तो आपके पास निम्नलिखित कार्य हैं: बहुभुज की एक काली और सफेद छवि को देखते हुए, आपके प्रोग्राम / फंक्शनल को पक्षों की संख्या वापस करना चाहिए।

कार्यक्रम को एक पुराने पंच कार्ड कंप्यूटर को खिलाया जाएगा, और आजकल पंचकार्ड बहुत महंगे हैं, आप अपने कार्यक्रम को यथासंभव छोटा बनाने की कोशिश करते हैं।

किनारों की लंबाई कम से कम 10 पिक्सेल है, और दो सहायक किनारों द्वारा गठित कोण कम से कम 10 ° है, लेकिन 170 ° (या फिर से 190 ° से अधिक) नहीं है। बहुभुज पूरी तरह से छवि के भीतर निहित है, और बहुभुज के साथ-साथ यह पूरक जुड़ा हुआ है (कोई पृथक द्वीप नहीं हैं) इसलिए यह इनपुट मान्य नहीं होगा:

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

स्कोरिंग

यह कोडगॉल्फ है, जिसका अर्थ है बाइट्स जीत में सबसे कम सबमिशन, आपके सबमिशन को हर टेस्ट केस के लिए किनारों की सही संख्या का पता लगाना होता है। (और सबमिशन अन्य मामलों के लिए भी काम करना चाहिए, केवल उन टेस्ट मामलों के लिए अनुकूलन की अनुमति नहीं है।)

यदि आप एक समाधान प्रस्तुत करना चाहते हैं, जो हर बार सही संख्या नहीं पाता है, तो आप उसे भी जमा कर सकते हैं, लेकिन बेहतर प्रदर्शन करने वाले सभी सबमिशन के पीछे इसे स्थान दिया जाएगा।

कृपया अपनी सबमिशन शीर्षक में कुल संख्या शामिल करें। (कुल त्रुटि पक्षों की वास्तविक संख्या और प्रत्येक आउटपुट के बीच पूर्ण अंतर का योग है)।

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

एन = 10

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

एन = 36

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

n = 7

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

एन = 5

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

यह एक परीक्षण का मामला नहीं है, सिर्फ जिज्ञासा से बाहर: इस इनपुट के लिए आपको कितने किनारे मिलते हैं?

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


मुझे आपके परीक्षण मामलों में कई कोण दिखाई देते हैं जो 170 ° से अधिक हैं। उदाहरण के लिए, आपके स्टार में सभी "गैर-बिंदु" कोण (केंद्र के करीब वाले)।
दरवाज़े

@ डॉर्कनोब यह छोटा कोण है जो 170 ° से कम होना चाहिए।
२०:२५ पर २

हां, लेकिन वे फिर से 190 ° से अधिक हैं। इस प्रतिबंध का उद्देश्य उन उदाहरणों को समाप्त करना है जहां दो सहायक पक्षों को अलग-अलग बताना मुश्किल है।
दोष

2
बहुभुज का आंतरिक रंग कौन सा है?
feersum

1
कार्यक्रम एक पुराने पंच कार्ड कंप्यूटर को खिलाया जाएगा, और आजकल पंचकार्ड बहुत महंगे हैं, आप बेहतर तरीके से अपने कार्यक्रम को यथासंभव छोटा बनाने की कोशिश करेंगे :-)
लुइस मेंडू

जवाबों:


12

अजगर 2 + पीआईएल, कोई त्रुटि नहीं, 313 307 बाइट्स

from Image import*
I=open(sys.argv[1])
w,h=I.size;D=I.getdata()
B={i%w+i/w*1j for i in range(w*h)if D[i]!=D[0]}
n=d=1;o=v=q=p=max(B,key=abs)
while p-w:
 p+=d*1j;e=2*({p}<B)+({p+d}<B)
 if e!=2:e%=2;d*=1j-e*2j;p-=d/1j**e
 if abs(p-q)>5:
    t=(q-v)*(p-q).conjugate();q=p;w=o
    if.98*abs(t)>t.real:n+=1;v=p
print n

कमांड लाइन पर एक छवि फ़ाइल नाम लेता है, और परिणाम को STDOUT में प्रिंट करता है।

सभी परीक्षणों के लिए सही परिणाम देता है, और सर्कल के लिए n = 28।

व्याख्या

एल्गोरिथ्म बहुभुज की परिधि के साथ चलने से काम करता है, और सामना किए गए कोने की संख्या (दिशा में परिवर्तन के रूप में पाया गया) की गिनती करता है। हम मूल से दूर पिक्सेल पर शुरू करते हैं, oजो एक शीर्ष होने की गारंटी है, और इसलिए, एक किनारे (यानी, अग्रभूमि पिक्सेल और एक पृष्ठभूमि पिक्सेल के बीच की सीमा) से सटे होने के लिए। हम अपनी स्थिति पर नज़र रखते हैं p, सबसे हालिया वर्टेक्स v, और सबसे हालिया "चेकपॉइंट", qजिनमें से सभी शुरू में बराबर हैं o। हम dवर्तमान पिक्सेल के सापेक्ष, किनारे की दिशा का भी ध्यान रखते हैं ; , या फिर यह मूल से दूर नहीं होगा। हम किनारे की ओर बढ़ते हैं, एक दिशा में , जैसे किdप्रारंभ में पूर्व की ओर इंगित करता है, जो कि एक सुरक्षित दिशा है, क्योंकि हम जानते हैं कि पूर्व की ओर एक धार हैodd हमारे बाएं ओर, यानी एक दक्षिणावर्त दिशा में। जब भी हम "किनारे से गिरते हैं", अर्थात, किसी भी स्थिति में जहां pबहुभुज के बाहर होता है, या जहां हमारे बाईं ओर पिक्सेल (यानी की दिशा में d) बहुभुज के अंदर होता है, हम समायोजन करते हैं pऔर dतदनुसार फिर से शुरू होने से पहले।

हर बार के बीच की दूरी pऔर पिछले चौकी, q, 5 से भी बड़ा हो जाता है, हम यह निर्धारित करने कि क्या हम के बीच एक शीर्ष पर पारित करने की कोशिश qऔर pहम बीच के कोण की तुलना vq(यानी, से वेक्टर vके लिए q) है, जो की सामान्य दिशा है बहुभुज की तरफ हम साथ चल रहे थे जब हम अंतिम चौकी पर पहुंचे थे, और qpअंतिम चौकी और वर्तमान स्थिति के बीच विस्थापन। यदि कोण लगभग 10 ° से अधिक है, तो हम निष्कर्ष निकालते हैं कि हम बहुभुज के एक अलग पक्ष के साथ चल रहे हैं, वर्टिकल काउंट बढ़ाएं और सेट करें v, वर्तमान वर्टेक्स, को p। प्रत्येक चेकपॉइंट पर, भले ही हमने एक वर्टेक्स का पता लगाया हो या नहीं, हम अपडेट करते हैंq , अंतिम चेकपॉइंट, कोp। हम इस फैशन को तब तक जारी रखते हैं जब तक कि हम वापस नहीं आ जाते हैं o, शुरुआती बिंदु, और पाए गए कोने की संख्या को वापस कर दें (ध्यान दें कि प्रारंभ में गिनती 1 है, चूंकि प्रारंभिक बिंदु, oस्वयं एक शीर्ष बिंदु है।)

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

n = 10 n = 36 n = 7 n = 5 वृत्त


इस विस्तृत विवरण के लिए धन्यवाद! मुझे आपके चित्र बहुत पसंद हैं!
दोष

यदि पूर्व की ओर एक छोर है o, तो क्या दूसरा छोर भी मूल से दूर नहीं होगा?
aditsu

1
@aditsu मुझे लगता है कि शब्दावली यहाँ थोड़ा भ्रमित हो सकती है। हम बहुभुज अर्थों में बहुभुज के किनारों के बारे में बात करते हैं , और किनारों को (पिक्सेल का एक सेट) बहुभुज, एक रेखापुंज ग्राफिक के रूप में। oमूल से सबसे दूर का अग्रभूमि पिक्सेल है, इसलिए इसके पूर्व का पिक्सेल एक पृष्ठभूमि पिक्सेल होना चाहिए, इसलिए हम कहते हैं कि पूर्व की ओर एक किनारे है o
इल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.