एक त्रिकोण के त्वचीय बिंदु की गणना करें


13

यह कुछ हद तक त्रिकोण के केंद्रों के समान है , लेकिन एक अलग बिंदु के साथ। फर्मेट प्वाइंट त्रिकोण में बिंदु पी ऐसी है कि एपी + बीपी + सी.पी. का मूल्य कम से कम है है। दो मामले हैं:

यदि कोई कोण 120 डिग्री से अधिक है, तो वह शीर्ष त्वचा बिंदु है। अन्यथा, एबीसी के प्रत्येक पक्ष पर समबाहु त्रिकोण बनाएं। त्रिभुज ABC के विपरीत समबाहु त्रिभुज के दूर के प्रत्येक शीर्ष को कनेक्ट करें। तीन समबाहु त्रिभुजों में से प्रत्येक के लिए ऐसा करने से तीनों रेखाओं के लिए एक ही सामान्य चौराहे पर परिणाम होता है, जो कि फ़र्मट पॉइंट है।

यह एक उचित मशीन पर 5 सेकंड के भीतर चलना चाहिए।

इनपुट : 3 अंकों का एक सेट, जरूरी नहीं कि पूर्णांक। यह एक नेस्टेड सरणी, स्ट्रिंग, ट्यूपल्स की सूची, आदि के रूप में लिया जा सकता है (जो भी आपकी भाषा के अनुकूल है)।

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

परीक्षण के मामले :

[[1, 1], [2, 2], [1, 2]] --> [1.2113248654051871, 1.788675134594813]
[[-1, -1], [-2, -1], [0, 0]] --> [-1, -1]
[[-1, -1], [1, -1], [0, 1]] --> [0, -0.42264973081037427]
[[0, 0], [0.5, 0.8660254037844386], [-5, 0]] --> [0, 0]
[[0, 0], [0, -5], [-0.8660254037844386, 0.5]] --> [0, 0]

यह कोड गोल्फ इतना कम कोड जीतता है!


1
क्या फ़्लोटिंग पॉइंट परिशुद्धता के वेतन वृद्धि में सभी बिंदुओं को आज़माना ठीक है और कुल दूरी को कम करने वाले को चुनना है?
xnor

1
@xnor यदि आप इसे 5 सेकंड के भीतर कर सकते हैं।
सोकटिनपेक

कितने महत्वपूर्ण आंकड़ों तक उत्पादन सही होना चाहिए? इसके अलावा, यह ठीक है अगर -0.0कुछ 0.0एस के स्थान पर आउटपुट है ?
आर। कप

@R। कप मैं 5 या 6 महत्वपूर्ण आंकड़ों के बारे में कहूंगा। इतना अधिक नहीं है कि राउंडिंग एरर की समस्या हो। दूसरे प्रश्न के लिए, यह ठीक लगता है।
सोक्तपिंक

जवाबों:


3

हास्केल, 346 291 285 बाइट्स

infixl 5£
z=zipWith
(?)=z(-)
t[a,b]=[-b,a]
a¤b=sum$z(*)a b
a%b=t a¤b
r a b c=[c%b/a%b,c%a/a%b]
x£y=2*x¤y<= -sqrt(x¤x*y¤y)
f[a,b,c]|a?b£c?b=b|a?c£b?c=c|b?a£c?a=a|[n,m,p,o]<-c?k a b c++a?k b c a=r[m,o][n,p][c%[n,m],a%[p,o]]
k a b c=map(/2)$z(+)a b?map(signum((b?a)%(c?a))*sqrt 3*)(t$b?a)

कुछ स्पष्टीकरण के साथ एक ही कोड

infixl 5£
z=zipWith

-- operator ? : difference of two vectors
(?)=z(-)            

-- function t : rotate a vector by +90 degrees
t[a,b]=[-b,a]       

-- operator ¤ : scalar product of two vectors ( a¤b = a0 * b0 + a1 * b1 )
a¤b=sum$z(*)a b     

-- operator % : "cross product" of two vectors ( a%b = a0 * b1 - a1 * b0 )
--      this returns actually the z coordinate of the 3d cross vector
--      other coordinates are nul since a and b are in the xy plan
a%b=t a¤b

-- function r : solves the system of two linear equations with two variables x0,x1 :
--      a0*x0 - b0*x1 = c0
--      a1*x0 - b1*x1 = c1
r a b c=[c%b/a%b,c%a/a%b]

-- operator £ : returns true if the angle between two vectors is >= 120 degrees
--      x¤y = ||x|| * ||y|| * cos(xyAngle)
--      so xyAngle>=120° is equivalent to : x¤y / (||x|| * ||y||) <= -0.5
x£y=2*x¤y<= -sqrt(x¤x*y¤y)

-- function k : takes 3 points A B C of a triangle and constructs the point C' 
--              of the equilateral triangle ABC' which is opposite to C:
--              C' = (A+B)/2 - ((+/-) sqrt(3)/2 * t(AB))
--
--      the sign +/- is given by the sign of the cross vector of AB an AC ((b?a)%(c?a))
--      which is >0 if the angle between AB and AC is positive
--      and <0 otherwise.
k a b c=map(/2)$z(+)a b?map(signum((b?a)%(c?a))*sqrt 3*)(t$b?a)

-- function f : returns the fermat point of a triangle
f[a,b,c]
    |a?b£c?b=b  -- return B if angle ABC >= 120°
    |a?c£b?c=c  -- return C if angle BCA >= 120°
    |b?a£c?a=a  -- return A if angle CAB >= 120°
    |[n,m,p,o]<-c?k a b c++a?k b c a= -- calculate the two segments C'C and A'A
        r[m,o][n,p][c%[n,m],a%[p,o]]  -- return their intersection

टेस्ट:

main = do 
    print $ f [[1, 1], [2, 2], [1, 2]]
    print $ f [[-1, -1], [-2, -1], [0, 0]]
    print $ f [[-1, -1], [1, -1], [0, 1]]
    print $ f [[0, 0], [0.5, 0.8660254037844386], [-5, 0]]
    print $ f [[0, 0], [0, -5], [-0.8660254037844386, 0.5]]

आउटपुट:

[1.2113248654051871,1.7886751345948126]
[-1.0,-1.0]
[0.0,-0.42264973081037427]
[0.0,0.0]
[0.0,0.0]

आप बाइट्स कैसे गिन रहे हैं? UTF-8 में £ और ¤ प्रत्येक के 2 बाइट्स हैं, और मुझे आईएसओ-8859-1 स्वीकार करने वाले हास्केल कंपाइलर के बारे में पता नहीं है। (आपके पास बहुत सारे मुफ्त 1-बाइट ASCII ऑपरेटर हैं, हालांकि, इसलिए इसे ठीक करना आसान है।)
एंडर्स केसोर्ग

मैं इसे अपने संपादक के साथ गिन रहा हूं जो वास्तव में पात्रों को गिनता है। मुझे नहीं पता था कि ये 2 बाइट्स थे, लेकिन वैसे भी, जैसा कि आपने कहा, मैं इसे अन्य 1 बाइट ऑपरेटरों द्वारा बदल सकता हूं। यह कोड GHC 7.8.3
डेमियन

GHC आपके कोड को तब संकलित करता है जब UTF-8 के साथ £और ¤2 बाइट ऑपरेटरों के रूप में एन्कोड किया जाता है, लेकिन जब ISO 1-8859-1 के साथ £और ¤1 बाइट ऑपरेटर के रूप में एन्कोडेड नहीं होता है । UTF-8 में उपलब्ध 1 बाइट ऑपरेटर हैं !, #, %, &, ?। आपको 2 बाइट ऑपरेटरों को प्रतिस्थापित करना चाहिए या अपनी बाइट गणना को समायोजित करना चाहिए।
एंडर्स केसरग

2

अजगर, 475 448 440 बाइट्स

आगे गोल्फ के लिए किसी भी मदद की सराहना की है।

from math import *
d=lambda x,y:((x[0]-y[0])**2+(x[1]-y[1])**2)**0.5
s=lambda A,B,C:(d(B,C), d(C,A), d(A,B))
j=lambda a,b,c:acos((b*b+c*c-a*a)/(2*b*c))
t=lambda a,b,c:1/cos(j(a,b,c)-pi/6)
b=lambda A,B,C,p,q,r:[(p*A[i]+q*B[i]+r*C[i])/(p+q+r) for i in [0,1]] 
f=lambda A,B,C:A if j(*s(A,B,C)) >= 2*pi/3 else B if j(*s(B,C,A)) >= 2*pi/3 else C if j(*s(C,A,B)) >= 2*pi/3 else b(A,B,C,d(B,C)*t(*s(A,B,C)),d(C,A)*t(*s(B,C,A)),d(A,B)*t(*s(C,A,B)))

Ungolfed:

from math import *
#distance between two points
d = lambda x,y: ((x[0]-y[0])**2+(x[1]-y[1])**2)**0.5

#given the points, returns the sides 
s = lambda A,B,C : (d(B,C), d(C,A), d(A,B))

#given the sides, returns the angle
j = lambda a,b,c : acos((b*b+c*c-a*a)/(2*b*c))

#given the sides, returns secant of that angle
t = lambda a,b,c: 1/cos(j(a,b,c)-pi/6)

#given the sides and the Trilinear co-ordinates, returns the Cartesian co-ordinates
b = lambda A,B,C,p,q,r: [(p*A[i]+q*B[i]+r*C[i])/(p+q+r) for i in [0,1]] 

#this one checks if any of the angle is >= 2π/3 returns that point else computes the point
f = lambda A,B,C: A if j(*s(A,B,C)) >= 2*pi/3 else B if j(*s(B,C,A)) >= 2*pi/3 else C if j(*s(C,A,B)) >= 2*pi/3 else b(A,B,C,d(B,C)*t(*s(A,B,C)),d(C,A)*t(*s(B,C,A)),d(A,B)*t(*s(C,A,B)))

इनपुट:

print('{}'.format(f([1, 1], [2, 2], [1, 2])))
print('{}'.format(f([-1, -1], [-2, -1], [0, 0])))
print('{}'.format(f([-1, -1], [1, -1], [0, 1])))
print('{}'.format(f([0, 0], [0.5, 0.8660254037844386], [-5, 0])))
print('{}'.format(f([0, 0], [0, -5], [-0.8660254037844386, 0.5])))

आउटपुट:

[1.2113248652983113, 1.7886751347016887]
[-1, -1]
[0.0, -0.42264973086764884]
[0, 0]
[0, 0]

2
from math import*एक बहुत ही सामान्य गोल्फ है। यह आपको piहार्ड कोडिंग के बजाय इसका उपयोग करने देगा (समान लंबाई 2*pi/3)। आप बहुत सारे व्हॉट्सएप को भी ड्रॉप कर सकते हैं जैसे d=lambda x,y:(...:।
FryAmTheEggman

2

पायथन 3.5, 1019 1016 998 982 969 953 बाइट्स:

from math import*
def H(z,a,b):c=complex;T=lambda A,B:abs(c(*A)-c(*B));d=T(z,a);e=T(z,b);f=T(a,b);g=[d,e,f];h=max(g);g.remove(h);i=acos((sum(i*i for i in g)-(h*h))/(2*g[0]*g[-1]));_=[[z,a],[z,b],[a,b]];j,s,t=cos,sin,atan;N=[[b,a]for a,b in zip([b,a,z],[max(i,key=i.get)if i!=''else''for i in[{(g[0]+(h*j(t(l))),g[1]+(h*s(t(l)))):T(k,(g[0]+(h*j(t(l))),g[1]+(h*s(t(l))))),(g[0]-(h*j(t(l))),g[1]-(h*s(t(l)))):T(k,(g[0]-(h*j(t(l))),g[1]-(h*s(t(l)))))}if l else{(g[0]+h,g[1]):T(k,(g[0]+h,g[1])),(g[0]-h,g[1]):T(k,(g[0]-h,g[1]))}if l==0else''for g,h,l,k in zip([((a[0]+b[0])/2,(a[1]+b[1])/2)for a,b in _],[(3**0.5)*(i/2)for i in[d,e,f]],[-1/p if p else''if p==0else 0for p in[((a[1]-b[1])/(a[0]-b[0]))if a[0]-b[0]else''for a,b in _]],[b,a,z])]])if b!=''];I=N[0][0][1];J=N[0][0][0];K=N[1][0][1];G=N[1][0][0];A=(N[0][1][1]-I)/(N[0][1][0]-J);B=I-(A*J);C=(K-N[1][1][1])/(G-N[1][1][0]);D=K-(C*G);X=(D-B)/(A-C);Y=(A*X)+B;return[[X,Y],[[a,b][h==d],z][h==f]][i>2.0943]

अविश्वसनीय रूप से अन्य उत्तरों की तुलना में लंबा है, लेकिन हे, कम से कम यह काम करता है! मुझे जो परिणाम मिला उससे मैं ज्यादा खुश नहीं हो सकता था क्योंकि मुझे अब तक की सबसे कठिन चुनौतियों में से एक होना चाहिए। मैं बहुत खुश हूँ कि यह वास्तव में काम करता है! : डी अब, अधिक तकनीकी नोटों पर:

  • यह फ़ंक्शन प्रत्येक ऑर्डर किए गए जोड़े को एक सूची या टुपल के रूप में लेता है। उदाहरण के लिए, H((1,1),(2,2),(1,2))काम करेगा, लेकिन ऐसा होगा H([1,1],[2,2],[1,2])
  • किसी पूर्णांक या फ्लोटिंग बिंदुओं की सूची में बिंदुओं के निर्देशांक को आउटपुट करता है, इस पर निर्भर करता है कि 120 कोण के बराबर या उससे अधिक कोण मौजूद है या नहीं।
  • कुछ इनपुट -0.0के 0.0लिए यह आउटपुट हो सकता है। उदाहरण के लिए, इनपुट के लिए आउटपुट [-1, -1], [1, -1], [0, 1]है [-0.0, -0.4226497308103744]मुझे उम्मीद है कि यह ठीक है, हालांकि अगर यह नहीं है, तो मैं इसे बदल दूंगा, हालांकि यह मुझे कुछ और बाइट्स देगा। यह ठीक है, जैसा कि ओपी ने पुष्टि की है
  • कम से कम करने के लिए सही ऊपर होना चाहिए 13करने के लिए 14महत्वपूर्ण आंकड़े।

मैं कोशिश करूंगा और समय के साथ इसे और गोल्फ करूंगा। एक स्पष्टीकरण, संभवतः बहुत लंबा, जल्द ही आ रहा है।

यह ऑनलाइन की कोशिश करो! (Ideone)


1

गणितज्ञ, 39 बाइट्स

Sum[Norm[p-{x,y}],{p,#}]~NArgMin~{x,y}&

कोने और एक बिंदु के बीच की दूरी के आधार पर एक समीकरण का निर्माण करता है {x,y}। फिर NArgMinउस समीकरण के लिए एक वैश्विक न्यूनतम खोजने के लिए फ़ंक्शन का उपयोग करता है, जो परिभाषा के अनुसार फ़र्मट पॉइंट होगा।

उदाहरण


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