বহুভুজের ক্ষেত্রটি সন্ধান করুন


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
আমি পক্ষগুলির সংখ্যা
সন্ধানের

এই সমস্যাটি পরিধি হিসাবে খুব সহজ, কিন্তু এটি ছাড়া এটি অবিশ্বাস্যভাবে কঠিন।
poi830

এটি পাঁচটি চেয়ে কম পক্ষ থাকলেও এটি সহজ, এটি কোড গল্ফের ক্ষেত্রে গুরুত্বপূর্ণ নয়।
নীল

উত্তর:


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 ডিগ্রির চেয়ে বড় হলে negativeণাত্মক হতে পারে।

পঠনযোগ্য বাস্তবায়ন:

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
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

@ এসক্টিনপেক প্রায় 15000 এর জন্য r*=1-1e-4এবং 150000 এর জন্য r*=1-1e-5
রেইনার পি।

@RainerP। এই দুটি মান একই।
মনিকা এর মামলা মামলা 19

1
@ soktinpk একটি নির্দিষ্ট উত্তরের জন্য ব্যতিক্রম করা সাধারণত ভাল ধারণা নয়।
সাইওস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.