একটি ত্রিভুজের ফারম্যাট পয়েন্ট গণনা করুন


13

এটি কিছুটা ত্রিভুজের কেন্দ্রগুলির সাথে মিল , তবে ভিন্ন বিন্দু সহ। ফার্মার পয়েন্ট ত্রিভুজ এবিসি পয়েন্ট পি যেমন যে পি + বিপি + + সিপি মান কমিয়ে আনা হয়। দুটি মামলা রয়েছে:

যদি 120 ডিগ্রির চেয়ে বেশি কোণ থাকে তবে সেই শীর্ষবিন্দুটি ফেরমেট পয়েন্ট। অন্যথায়, এবিসির প্রতিটি পক্ষের সমান ত্রিভুজ আঁকুন। প্রতিটি সমবাহু ত্রিভুজের সুদূর প্রান্তকে ত্রিভুজের এবিসির বিপরীতম প্রান্তের সাথে সংযুক্ত করুন। তিনটি সমান্তরাল ত্রিভুজগুলির প্রত্যেকটির জন্য এটি করার ফলে তিনটি রেখার জন্য একটি একক সাধারণ মোড়কে বিভক্ত করা যায়, এটি ফেরমাট পয়েন্ট।

এটি একটি যুক্তিসঙ্গত মেশিনে 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 সেকেন্ডের মধ্যে করতে পারেন।
soktinpk

কতগুলি গুরুত্বপূর্ণ পরিসংখ্যানের আউটপুট সঠিক হওয়া উচিত? এছাড়াও, -0.0কিছু 0.0s এর জায়গায় যদি আউটপুট হয় তবে তা ঠিক আছে ?
আর কাপ,

@R। কাপ আমি প্রায় 5 বা 6 উল্লেখযোগ্য পরিসংখ্যান বলতে চাই। রাউন্ডিং ত্রুটিগুলির একটি সমস্যা হওয়া উচিত এমন খুব বেশি কিছু নেই। দ্বিতীয় প্রশ্ন হিসাবে, এটা ঠিক মনে হয়।
soktinpk

উত্তর:


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]

আপনি কীভাবে বাইট গণনা করছেন? ইউটিএফ -8 এ £ এবং each প্রতি 2 বাইট, এবং আমি আইএসও -8859-1 কে গ্রহণ করে এমন একটি হাস্কেল সংকলক জানি না। (আপনার কাছে প্রচুর ফ্রি 1-বাইট এএসসিআইআই অপারেটর রয়েছে, তবে এটি ঠিক করা সহজ))
অ্যান্ডারস কাসরগ

আমি এটি আমার সম্পাদকের সাথে গণনা করছি যা প্রকৃতপক্ষে চরিত্রগুলি গণনা করে। আমি জানতাম না যে এটি 2 বাইট, তবে যাইহোক, আপনি যেমন বলেছিলেন, আমি এটি অন্য 1 বাইট অপারেটর দ্বারা প্রতিস্থাপন করতে পারি। এই কোডটি জিএইচসি 7.8.3
ড্যামিয়েন

জিটিএইচসি আপনার কোডটি ইউটিএফ -8 হিসাবে 2 টি বাইট অপারেটর হিসাবে £এবং ¤এনকোডেড হওয়ার পরে, যখন আইএসও -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 হয় ...
বেলিন্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.