एक बहुभुज का क्षेत्रफल ज्ञात कीजिए


9

s1, s2, s3... s_nएक सर्कल में अंकित एन-गॉन की लगातार लंबाई को देखते हुए , इसका क्षेत्र ढूंढें। आप मान सकते हैं कि बहुभुज मौजूद है। इसके अलावा, बहुभुज उत्तल होगा और स्व-प्रतिच्छेदन नहीं होगा, जो विशिष्टता की गारंटी देने के लिए पर्याप्त है। बिल्ट-इन जो विशेष रूप से इस चुनौती को हल करते हैं, साथ ही साथ अंतर्निहित कार्य जो कि परिधि या परिधि की गणना करते हैं, पर प्रतिबंध लगा दिया जाता है (यह इस चुनौती के पिछले संस्करण से अलग है)।

इनपुट: चक्रीय बहुभुज की ओर की लंबाई; एक फ़ंक्शन, स्टडिन आदि के मापदंडों के रूप में लिया जा सकता है।

आउटपुट: बहुभुज का क्षेत्र।

उत्तर 6 दशमलव स्थानों पर सटीक होना चाहिए और एक उचित लैपटॉप पर 20 सेकंड के भीतर चलना चाहिए।

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

विशिष्ट परीक्षण के मामले:

[3, 4, 5] --> 6
[3, 4, 6] --> 5.332682251925386
[3, 4, 6, 7] --> 22.44994432064365
[5, 5, 5, 5] --> 25
[6, 6, 6, 6, 6] --> 61.93718642120281
[6.974973020933265, 2.2393294197257387, 5.158285083300981, 1.4845682771595603, 3.5957940796134173] --> 21.958390804292847
[7.353566082457831, 12.271766915518073, 8.453884922273897, 9.879017670784675, 9.493366404245332, 1.2050010402321778] --> 162.27641678140589

टेस्ट केस जनरेटर:


7
मैं इसकी परिधि को खोजने का एक आसान तरीका जानता हूं।
mIllIbyte

1
मुझे पता है कि पक्षों की संख्या का पता लगाने का एक आसान तरीका है
लुइस मेंडो

इस समस्या को बहुत आसान दिया गया है, लेकिन यह बिना अविश्वसनीय रूप से कठिन है।
पोइ .३०

यह आसान भी है अगर पांच से कम पक्ष हैं, न कि यह कोड गोल्फ में मायने रखता है।
नील

जवाबों:


5

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

from math import*
C=sorted(input());l,h=C[-1]/2,sum(C)
while h-l>1e-9:m=l+h;a=[asin(c/m)for c in C[:-1]];f=pi-sum(a);l,h=[l,m/2,h][m*sin(f)<C[-1]:][:2]
print sum(l*l*sin(2*t)for t in a+[f])/2

त्रिज्या को खोजने के लिए एक द्विआधारी खोज का उपयोग करता है, फिर कोण / त्रिज्या द्वारा प्रत्येक खंड के क्षेत्र की गणना करता है।

यह त्रिज्या को पहले सभी लेकिन सबसे बड़े कॉर्ड कोण को समेट कर, और शेष कोर्ड में शेष कोण की जाँच करता है। फिर उन कोणों का उपयोग प्रत्येक खंड के क्षेत्र की गणना करने के लिए भी किया जाता है। एक खंड का क्षेत्र ऋणात्मक हो सकता है, यदि यह कोण 180 डिग्री से बड़ा है।

पठनीय कार्यान्वयन:

import math

def segment_angles(line_segments, r):
    return [2*math.asin(c/(2*r)) for c in line_segments]

def cyclic_ngon_area(line_segments):
    line_segments = list(sorted(line_segments))
    lo, hi = max(line_segments) / 2, sum(line_segments)
    while hi - lo > 1e-9:
        mid = (lo + hi) / 2
        angles = segment_angles(line_segments[:-1], mid)
        angles.append(2*math.pi - sum(angles))
        if 2 * mid * math.sin(angles[-1]/2) < line_segments[-1]:
            lo = mid
        else:
            hi = mid
    return sum([lo*lo * math.sin(a) / 2 for a in angles])

क्या यह काम करता है अगर केंद्र बहुभुज के बाहर है? (उदाहरण के लिए, एक त्रिभुज जिसकी लंबाई 6, 7, 12 है)। कभी-कभी sqrt(4**2 - c**2/4)नकारात्मक होने की आवश्यकता होती है, जब कोण से अधिक होता है pi
1957 में soktinpk

@soktinpk मैंने अपना जवाब तय किया।
orlp

0

ऑक्टेव, 89 बाइट्स

r=sum(s=input(''));while sum(a=asin(s/2/r))<pi r*=1-1e-4;b=a;end;disp(sum(cos(b).*s/2*r))

व्याख्या

कोण aलंबाई का एक खंड से फैला sहै 2*asin(s/2/r), एक circumradius दिया r। इसका क्षेत्रफल है cos(a)*s/2*r

कलन विधि

  1. rपरिधि जैसे कुछ बड़े पर सेट करें ।
  2. यदि संचयी कोण से छोटा है 2pi, तो rचरण 2 को कम करें और दोहराएं।
  3. क्षेत्र की गणना करें।

औसतन, rइसे सेट करने के लिए कितने पुनरावृत्तियों को लिया जाता है? (जिज्ञासा से बाहर)
soktinpk

कोई रास्ता नहीं है यह आवश्यक परिशुद्धता है। आप इसे कम करने के लिए बार-बार त्रिज्या को 0.9999 से गुणा करते हैं, इससे आवश्यक 6 दशमलव सटीकता को कम करना बहुत आसान हो जाता है।
orlp

@soktinpk लगभग 15000 के लिए r*=1-1e-4और 150000 के लिए r*=1-1e-5
रेनर पी।

@RainerP। वे दो मूल्य समान हैं।
निधि मोनिका का मुकदमा

1
@soktinpk यह आम तौर पर एक विशिष्ट जवाब के लिए एक अपवाद बनाने के लिए एक अच्छा विचार नहीं है।
साइयो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.