उत्तल हल (2D) में बिंदु


10

पृष्ठभूमि

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

इनपुट

N+12-डी निर्देशांक ( N >= 3) STDINसामान्य प्रारूप में (अन्य सामान्य गोल्फ इनपुट के साथ ) के माध्यम से पारित (निम्नलिखित दशमलव की संख्या भिन्न हो सकती है, लेकिन आप यह मान सकते हैं कि यह "उचित" है और प्रत्येक संख्या को फ्लोट के रूप में दर्शाया जा सकता है):

0.00;0.00000
1;0.00
0.000;1.0000
-1.00;1.000000

उत्पादन

एक सत्य मूल्य STDOUT(या समतुल्य) के लिए छपा हुआ है अगर सूची में पहला बिंदु ( (0.00;0.00000)ऊपर उदाहरण में) अन्य एन बिंदुओं के उत्तल पतवार में है, और एक मिथ्या मूल्य अन्यथा।

यह , इसलिए बाइट्स जीत में सबसे छोटा समाधान है।

  • सीमा के मामले : यदि आप उत्तल हल की सीमा पर (यानी एक तरफ या पतवार के बाहरी सीमा पर एक शिखर पर) झूठ बोलते हैं, तो आप किसी भी मूल्य (लेकिन दुर्घटना नहीं) कर सकते हैं, क्योंकि यह एक शून्य संभावना है घटना (किसी भी उचित संभावना के तहत)।

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

टेस्ट


3
"तदर्थ डेटा संरचना" क्या है?
डेविड डिक

"प्राथमिक कार्य / ऑपरेटर" बहुत अधिक अस्पष्ट है।
xnor

@ दाविदकरहर: एक बहुभुज, या एक त्रिभुज, या एक खंड (कुछ भी जो केवल ज्यामितीय समस्याओं को हल करने के लिए मौजूद है) की तरह है।
एलेक्जेंडर हेलम

2
@AlexandreHalm आपके संपादन में बहुत मदद मिली। मुझे लगता है कि "प्राथमिक" सही शब्द नहीं है। मैंने सोचा था कि यह सामान्य प्रयोजन के बिल्ट-इन को खत्म sortकर देगा round। मुझे लगता है कि यह स्पष्ट है कि केवल ज्यामिति के लिए विशेष रूप से बनाए गए कुछ भी अनुमति नहीं है। हालांकि, वैक्टर के रूप में दो सूचियों को जोड़ने के लिए एक समारोह के बारे में क्या? या एक जटिल संख्या के तर्क (कोण) को खोजने के लिए एक फ़ंक्शन?
xnor

1
यही कारण है कि हीरे का अनुरोध है कि लोग नई चुनौतियों को पोस्ट करने से पहले सैंडबॉक्स का उपयोग करें
बिल्ली

जवाबों:


9

जे, 40 39 34 बाइट्स

3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-

एक अनाम डियाडिक फंक्शन, एक बिंदु, पी , इसके तर्कों में से एक के रूप में, और अंक की एक सूची, पी , अन्य तर्क के रूप में (यह कोई फर्क नहीं पड़ता कि कौन सा तर्क है), और वापस आ रहा है , 0या 1यदि पी बाहर है या क्रमशः पी के उत्तल पतवार के अंदर । बिंदु p , और P में बिंदुओं को जटिल संख्याओं के रूप में लिया जाता है।

उदाहरण

  is_inside =: 3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-

  0.5j0.5  is_inside  0j0 0j1 1j0 1j1
1
  1.5j0.5  is_inside  0j0 0j1 1j0 1j1
0

या ...

पायथन 2, फ़ंक्शन, 121 103, पूरा कार्यक्रम, 162

पायथन 3, 149 बाइट्स

import sys,cmath as C
p,q,*P=[complex(*eval(l.replace(*";,")))for l in sys.stdin]
A=[C.phase((r-p)/(q-p+(q==p)))for r in P]
print(max(A)-min(A)>C.pi)

मूल पोस्ट के रूप में एक ही प्रारूप में, STDIN के माध्यम से इनपुट लेता है, और एक बूलियन मूल्य प्रिंट करता है जो यह दर्शाता है कि पी पी के उत्तल पतवार में है या नहीं


व्याख्या

कार्यक्रम परीक्षण अधिकतम और न्यूनतम (हस्ताक्षरित) के बीच का अंतर किसी भी बिंदु के बीच कोण है कि क्या आर में पी , पी , और एक निश्चित मनमाना बिंदु क्ष में पी (हम सिर्फ में पहला बिंदु का उपयोग पी ), 180 से भी कम है °। दूसरे शब्दों में, यह परीक्षण करता है कि क्या पी के सभी बिंदु 180 ° या उससे कम के कोण में निहित हैं, पी के आसपास । पी के उत्तल पतवार में है पी यदि और केवल यदि इस हालत झूठी है।


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

To (अस्थायी रूप से) इस लाइन को ढूंढें, हम शुरुआत करते हैं l को p के माध्यम से रेखा बनाते हैं और P में पहला बिंदु । हम फिर पी में बाकी बिंदुओं पर पुनरावृति करते हैं ; यदि अंकों में से एक l के बाईं ओर है (हम कुछ दिशात्मकता मान लेते हैं, तो बाएं या दाएं वास्तव में कोई फर्क नहीं पड़ता,) हम l को p और उस बिंदु से गुजरने वाली लाइन से प्रतिस्थापित करते हैं , और जारी रखते हैं। पी के सभी पर चलने के बाद , यदि (और केवल अगर) पी उत्तल पतवार के बाहर है, तो पी में सभी बिंदु एल के दाईं ओर (या) होना चाहिए । हम जांच करते हैं कि पी में बिंदुओं पर दूसरे पास का उपयोग करना

पायथन 2, 172 बाइट्स

import sys
P=[eval(l.replace(*";,"))for l in sys.stdin]
x,y=P.pop(0)
C=lambda(a,b),(c,d):(a-x)*(d-y)-(b-y)*(c-x)>0
l=reduce(lambda*x:x[C(*x)],P)
print any(C(l,q)for q in P)


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

यह अच्छी तरह से काम करेगा अगर पी के उत्तल पतवार के बाहर है पी , जिस स्थिति में करने के लिए-बाएं की वास्तव में एक आदेश संबंध है, लेकिन जब टूट सकता है पी (उदाहरण के लिए उत्तल पतवार के अंदर है, यह पता लगाने की कोशिश क्या होगा यदि हम इस एल्गोरिथ्म को चलाते हैं, जहां P में अंक एक नियमित पेंटागन के कोने हैं, काउंटर-क्लॉकवाइज चल रहा है, और p इसका केंद्र है।) समायोजित करने के लिए, हम एल्गोरिथ्म को थोड़ा बदल देते हैं: हम P में एक बिंदु q का चयन करते हैं , और बिसेक्ट करते हैं। पी रेखा के साथ के माध्यम से गुजर पी और क्यू (यानी, हम विभाजन पी के आसपास क्षwrt-to-left-to-the।) अब हमारे पास एक "बाएँ भाग" और P का एक "दाएँ भाग" है , प्रत्येक में एक समतल सम्‍मिलित है, ताकि बाएँ-से-बाएँ प्रत्येक पर एक ऑर्डर रिलेशन हो; हम बाएं हिस्से का न्यूनतम भाग, और दाएं भाग का अधिकतम भाग, और ऊपर वर्णित अनुसार उनकी तुलना करते हैं। बेशक, हमें P को शारीरिक रूप से द्विभाजित करने की आवश्यकता नहीं है , हम बस P में प्रत्येक बिंदु को वर्गीकृत कर सकते हैं क्योंकि हम एक पास में न्यूनतम और अधिकतम की तलाश करते हैं।

पायथन 2, 194 बाइट्स

import sys
P=[eval(l.replace(*";,"))for l in sys.stdin]
x,y=P.pop(0)
C=lambda(a,b),(c,d):(a-x)*(d-y)-(b-y)*(c-x)>0
l=r=P[0]
for q in P:
 if C(P[0],q):l=q*C(l,q)or l
 elif C(q,r):r=q
print C(l,r)

किसी भी तरह से आप अपने समाधान कर सकते हैं (कम से कम पायथन एक, मुझे कोई सुराग नहीं है अगर J वह कर सकता है) STIN से इनपुट ले? मुझे लगता है कि स्तरीय खेल मैदान के साथ समाधानों की तुलना करना आसान होगा। यह मानते हुए कि इनपुट पहले से ही जटिल संख्याओं या बिंदुओं का एक पूर्वनिर्मित सेट है, एक खिंचाव IMO का एक सा है।
एलेक्जेंडर हेल्म

@AlexandreHalm ने पूरा कार्यक्रम जोड़ा।
एल डे

आपको अपना समाधान प्रति भाषा में एक उत्तर में विभाजित करना चाहिए।
मेघो

4

ऑक्टेव, 82 72 बाइट्स

d=dlmread(0,";");i=2:rows(d);~isna(glpk(i,[d(i,:)';~~i],[d(1,:)';1]))&&1

यह विचार करना है कि क्या रेखीय कार्यक्रम मिनट {c'x: Ax = b, e'x = 1, x> = 0} का एक समाधान है, जहाँ e सभी का सदिश है, A के स्तंभ निर्देशांक हैं बिंदु बादल, और b परीक्षण बिंदु है, और c मनमाना है। दूसरे शब्दों में, हम A के स्तंभों के उत्तल संयोजन के रूप में b को दर्शाने का प्रयास करते हैं।

स्क्रिप्ट चलाने के लिए, उपयोग करें octave -f script.m <input.dat


2

आर, 207 बाइट्स

d=read.csv(file("stdin"),F,";")
q=function(i,j,k)abs(det(as.matrix(cbind(d[c(i,j,k),],1))))
t=function(i,j,k)q(i,j,k)==q(1,i,j)+q(1,i,k)+q(1,j,k)
any(apply(combn(2:nrow(d),3),2,function(v)t(v[1],v[2],v[3])))

स्क्रिप्ट एसटीडीआईएन से अपने इनपुट लेती है, जैसे Rscript script.R < inputFile

यह Nअंतिम बिंदुओं (अंतिम पंक्ति apply(combn(...) से सभी त्रिकोण उत्पन्न करता है और जाँचता है कि tफ़ंक्शन का उपयोग करते हुए त्रिकोण में पहला बिंदु है या नहीं ।

tअगर तय करने के लिए क्षेत्र विधि का उपयोग करता Uहै ABC(लेखन: (ABC)के क्षेत्र के लिए ABC) Uमें है ABCiff (ABC) == (ABU) + (ACU) + (BCU)। इसके अलावा, क्षेत्रों को निर्धारक सूत्र का उपयोग करके गणना की जाती है ( वुल्फराम से अच्छा डेमो के लिए यहां देखें )।

मुझे संदेह है कि यह समाधान मेरे अन्य की तुलना में संख्यात्मक त्रुटियों के लिए अधिक प्रवण है, लेकिन यह मेरे परीक्षण मामलों पर काम करता है।


0

आर, 282 बाइट्स

d=read.csv(file("stdin"),F,";")
p=function(a,b)a[1]*b[1]+a[2]*b[2]
t=function(a,b,c){A=d[a,];
U=d[1,]-A
B=d[b,]-A
C=d[c,]-A
f=p(C,C)
g=p(B,C)
h=p(U,C)
i=p(B,B)
j=p(U,B)
k=f*i-g*g
u=i*h-g*j
v=f*j-g*h
min(u*k,v*k,k-u-v)>0}
any(apply(combn(2:nrow(d),3),2,function(v)t(v[1],v[2],v[3])))

स्क्रिप्ट एसटीडीआईएन से अपने इनपुट लेती है, जैसे Rscript script.R < inputFile

यह Nअंतिम बिंदुओं (अंतिम पंक्ति apply(combn(...) से सभी त्रिकोण उत्पन्न करता है और जाँचता है कि tफ़ंक्शन का उपयोग करते हुए त्रिकोण में पहला बिंदु है या नहीं ।

tयह निर्धारित करने के लिए कि क्या Uहै ABC: ( वेक्टर के XYलिए लेखन ) के बाद से विमान के लिए एक आधार है (जहां पतित मामलों को छोड़कर जहां A, B, C संरेखित हैं) Xको लिखने के लिए barycentric विधि का उपयोग करता है , जैसा कि इस त्रिकोण में लिखा जा सकता है और है । उदाहरण के लिए और अधिक विस्तृत विवरण और एक अच्छे इंटरैक्टिव चार्ट के लिए यहां देखें । ध्यान दें: कुछ वर्ण और से बचने के DIV0 त्रुटियों को बचाने के लिए, हम केवल के लिए एक शॉर्टकट की गणना और और एक संशोधित परीक्षण ( )।Y(AB,AC)AUAU = u.AB + v.ACUu > 0 && v > 0 && u+v < 1uvmin(u*k,v*k,k-u-v)>0

केवल गणितीय इस्तेमाल किया ऑपरेटर हैं +, -, *, min()>0

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