পাইথন, 1,291 1,271 1,225 বাইট
মার্টিন যেমন উল্লেখ করেছেন, এই সমস্যাটি তার দুর্দান্ত রাবার ব্যান্ড চ্যালেঞ্জ থেকে অনেকাংশে হ্রাস করা যেতে পারে । সেই চ্যালেঞ্জের পরিভাষা ব্যবহার করে, আমরা নখের দ্বিতীয় সেট হিসাবে বদ্ধ ক্ষেত্রের সীমানাতে বৃত্তগুলির মধ্যে ছেদ করার পয়েন্টগুলি গ্রহণ করতে পারি :
রাবার ব্যান্ড হিসাবে আমরা বদ্ধ অঞ্চলের অভ্যন্তরে দুটি শেষ পয়েন্টের মধ্যে যে কোনও পথ পি নিতে পারি । এরপরে আমরা একটি (স্থানীয়ভাবে) ন্যূনতম পাথ তৈরির জন্য রাবার-ব্যান্ড সমস্যার সমাধানের জন্য আবেদন করতে পারি। অবশ্যই চ্যালেঞ্জটি হ'ল এই জাতীয় পথ পি বা আরও সুনির্দিষ্টভাবে সন্ধান করার জন্য যথেষ্ট সন্ধান করা সন্ধানের পথগুলি সন্ধান করা যাতে তাদের মধ্যে কমপক্ষে একটি বিশ্বব্যাপী ন্যূনতম পাথ তৈরি করে (লক্ষ্য করুন যে প্রথম পরীক্ষার ক্ষেত্রে আমাদের কমপক্ষে একটি পথ প্রয়োজন সমস্ত সম্ভাবনা কভার করুন, এবং দ্বিতীয় পরীক্ষার ক্ষেত্রে কমপক্ষে দুটি।)
একটি নিষ্কলুষ দৃষ্টিভঙ্গি কেবল সমস্ত সম্ভাব্য পাথ চেষ্টা করে দেখার জন্য: সংলগ্ন প্রতিটি ক্রম (যেমন ছেদ করার জন্য) দুটি প্রান্তকে সংযুক্ত করে, তাদের কেন্দ্রগুলি বরাবর পথ ধরুন (যখন দুটি বৃত্ত ছেদ করে, তাদের কেন্দ্রগুলির মধ্যে বিভাগটি সর্বদা তাদের ইউনিয়নের মধ্যে থাকে) ।) যদিও এই পদ্ধতির প্রযুক্তিগতভাবে সঠিক, এটি একটি হাস্যকরভাবে প্রচুর সংখ্যক পথের দিকে নিয়ে যেতে পারে। আমি কয়েক সেকেন্ডের মধ্যে এই পদ্ধতির সাহায্যে প্রথম পরীক্ষার ক্ষেত্রে সমাধান করতে সক্ষম হয়েছি, দ্বিতীয়টি চিরতরে নিল। তবুও, আমরা এই পদ্ধতিটিকে একটি প্রাথমিক পয়েন্ট হিসাবে নিতে পারি এবং আমাদের পরীক্ষা করতে হবে এমন রাস্তার সংখ্যা হ্রাস করার চেষ্টা করতে পারি। এই যা অনুসরণ করে।
আমরা মূলত চেনাশোনাগুলির গ্রাফটিতে গভীরতা-প্রথম অনুসন্ধান করে আমাদের পথগুলি তৈরি করি। আমরা অনুসন্ধানের প্রতিটি ধাপে সম্ভাব্য অনুসন্ধানের দিকনির্দেশগুলি দূর করার জন্য একটি উপায় খুঁজছি।
মনে করুন যে কোনও এক সময় আমরা একটি বৃত্ত এ আছি , এর দুটি সন্নিহিত বৃত্ত বি এবং সি রয়েছে , যা একে অপরের সাথে সংলগ্নও রয়েছে। আমরা থেকে পেতে পারেন একজন থেকে সি পরিদর্শন করে বি (বিপরীতভাবে এবং ভাইস,) তাই আমরা মনে হতে পারে যে পরিদর্শন উভয় বি এবং সি থেকে সরাসরি একটি অপ্রয়োজনীয়। দুর্ভাগ্যক্রমে, এটি ভুল, যেমন এই চিত্রটি দেখায়:
চিত্রণ পয়েন্ট দুই এন্ড পয়েন্ট হন, আমরা দেখতে পারি যে থেকে গিয়ে একটি থেকে সি মাধ্যমে বি আমরা আরও দীর্ঘ পথ পাবো।
এটি সম্পর্কে কীভাবে: যদি আমরা A → B এবং A → C উভয় পদক্ষেপগুলি পরীক্ষা করে দেখি তবে A → B → C বা A → C → B পরীক্ষা করা অপ্রয়োজনীয় , যেহেতু তারা ছোট পথগুলিতে ফলাফল করতে পারে না। আবার ভুল:
মুল বক্তব্যটি হ'ল বিশুদ্ধ সংলগ্নতা ভিত্তিক যুক্তিগুলি এটি কাটছে না; আমাদের সমস্যার জ্যামিতিও ব্যবহার করতে হবে। উপরোক্ত দুটি উদাহরণের মধ্যে যা মিল রয়েছে (সেইসাথে বৃহত্তর স্কেলের দ্বিতীয় টেস্ট-কেস) তা হল এটি আবদ্ধ অঞ্চলে একটি "গর্ত" রয়েছে। এটি এ সত্যটি প্রকাশ করে যে সীমান্তের কয়েকটি পয়েন্ট অফ ইন্টারসেস — আমাদের "নখ" ত্রিভুজের মধ্যেই রয়েছে △ এবিসি যার শীর্ষে বৃত্তের কেন্দ্র:
এটি যখন ঘটে তখন একটি সুযোগ থাকে যে এ থেকে বি তে এবং এ থেকে সিতে যাওয়ার ফলে বিভিন্ন পথের ফলস্বরূপ। আরও গুরুত্বপূর্ণ, যখন এটি ঘটে না (যেমন, যদি এ , বি এবং সি এর মধ্যে কোনও ফাঁক না থাকে ) তবে এটি গ্যারান্টিযুক্ত যে সমস্ত পাথ A → B → C এবং A → C দিয়ে শুরু হবে এবং যা অন্যথায় সমান result একই স্থানীয়ভাবে ন্যূনতম পাথ, অত যদি আমরা পরিদর্শন বি আমরা করার প্রয়োজন নেই আর আেসন না সি থেকে সরাসরি একটি ।
আমাদের বর্জন পদ্ধতি এই বিশালাকার আমাদের: আমরা একটি বৃত্ত আছেন কখন একজন , আমরা একটি তালিকা রাখা এইচ সংলগ্ন চেনাশোনা আমরা পরিদর্শন করেছেন। এই তালিকাটি প্রাথমিকভাবে খালি। এ , বি কেন্দ্র এবং বি এর সাথে সংলগ্ন এইচ এর যে কোনও বৃত্তের দ্বারা গঠিত সমস্ত ত্রিভুজগুলিতে কোনও "নখ" থাকলে আমরা একটি সংলগ্ন বৃত্ত বি পরিদর্শন করি । এই পদ্ধতিটি নাটকীয়ভাবে প্রথম পরীক্ষার ক্ষেত্রে আমাদের কেবলমাত্র 1 টি এবং দ্বিতীয়টিতে 10 টি পরীক্ষা করতে হবে of
আরও কয়েকটি নোট:
আমরা আরও আরও যে পরীক্ষাগুলি পরীক্ষা করি তার সংখ্যা হ্রাস করা সম্ভব, তবে এই সমস্যাটির মাত্রার জন্য এই পদ্ধতিটি যথেষ্ট ভাল।
আমি আমার সমাধান থেকে রাবার-ব্যান্ড চ্যালেঞ্জের আলগোরিদিম ব্যবহার করেছি । যেহেতু এই অ্যালগরিদমটি বর্ধনশীল তাই এটি পাথ সন্ধানের প্রক্রিয়াটিতে খুব সহজেই সংহত করা যায়, যাতে আমরা পাশাপাশি চলতে চলতে পথকে ন্যূনতম করি। যেহেতু অনেকগুলি পাথ একটি প্রারম্ভিক বিভাগটি ভাগ করে, তাই যখন আমাদের প্রচুর পথ থাকে তখন এটি পারফরম্যান্সে উল্লেখযোগ্যভাবে উন্নতি করতে পারে। বৈধ পাথের চেয়ে অনেক বেশি মৃত-প্রান্ত থাকলে এটি কার্য সম্পাদনকেও আঘাত করতে পারে। যে কোনও উপায়ে প্রদত্ত পরীক্ষার ক্ষেত্রে পৃথকভাবে প্রতিটি পাথের জন্য অ্যালগরিদম সম্পাদন করা যথেষ্ট ভাল।
একটি সমাধান রয়েছে যেখানে এই সমাধানটি ব্যর্থ হতে পারে: সীমানার উপরের কোনও বিন্দু যদি দুটি স্পর্শকাতর বৃত্তের ছেদ বিন্দু হয় তবে কিছু পরিস্থিতিতে ফলাফলটি ভুল হতে পারে। এটি রাবার-ব্যান্ড অ্যালগরিদম যেভাবে কাজ করে তার কারণে এটি ঘটে। কিছু সংশোধন করার মাধ্যমে এই কেসগুলিও পরিচালনা করা সম্ভব, তবে, হেই, এটি ইতিমধ্যে যথেষ্ট দীর্ঘ।
# First test case
I={((32.,42.),64.),((112.,99.),59.),((141.,171.),34.),((157.,191.),28.),((177.,187.),35.),((244.,168.),57.),((289.,119.),20.),((299.,112.),27.),((354.,59.),58.),((402.,98.),23.),((429.,96.),29.),((424.,145.),34.),((435.,146.),20.),((455.,204.),57.),((430.,283.),37.),((432.,306.),48.),((445.,349.),52.),((424.,409.),59.),((507.,468.),64.)}
# Second test case
#I={((32.,42.),64.),((112.,99.),59.),((141.,171.),34.),((157.,191.),28.),((177.,187.),35.),((244.,168.),57.),((289.,119.),20.),((299.,112.),27.),((354.,59.),58.),((402.,98.),23.),((429.,96.),29.),((424.,145.),34.),((435.,146.),20.),((455.,204.),57.),((430.,283.),37.),((432.,306.),48.),((445.,349.),52.),((424.,409.),59.),((507.,468.),64.),((180.,230.),39.),((162.,231.),39.),((157.,281.),23.),((189.,301.),53.),((216.,308.),27.),((213.,317.),35.),((219.,362.),61.),((242.,365.),42.),((288.,374.),64.),((314.,390.),53.),((378.,377.),30.),((393.,386.),34.)}
from numpy import*
V=array;X=lambda u,v:u[0]*v[1]-u[1]*v[0];L=lambda v:dot(v,v)
e=V([511]*2)
N=set()
for c,r in I:
for C,R in I:
v=V(C)-c;d=L(v)
if d:
a=(r*r-R*R+d)/2/d;q=r*r/d-a*a
if q>=0:w=V(c)+a*v;W=V([-v[1],v[0]])*q**.5;N|={tuple(t)for t in[w+W,w-W]if all([L(t-T)>=s**2-1e-9 for T,s in I])}
N=map(V,N)
def T(a,b,c,p):H=[X(p-a,b-a),X(p-b,c-b),X(p-c,a-c)];return min(H)*max(H)>=0
def E(a,c,b):
try:d=max((X(n-a,b-a)**2,id(n),n)for n in N if T(a,b,c,n)*X(n-b,c-b)*X(n-c,a-c))[2];A=E(a,c,d);B=E(d,c,b);return[A[0]+[d]+B[0],A[1]+[sign(X(c-a,b-c))]+B[1]]
except:return[[]]*2
def P(I,c,r,A):
H=[];M=[""]
if L(c-e)>r*r:
for C,R in I:
if L(C-c)<=L(r+R)and all([L(h-C)>L(R+s)or any([T(c,C,h,p)for p in N])for h,s in H]):v=V(C);H+=[(v,R)];M=min(M,P(I-{(C,R)},v,R,A+[v]))
return M
A+=[e]*2;W=[.5]*len(A)
try:
while 1:
i=[w%1*2or w==0for w in W[2:-2]].index(1);u,a,c,b,v=A[i:i+5];A[i+2:i+3],W[i+2:i+3]=t,_=E(a,c,b);t=[a]+t+[b]
for p,q,j,k in(u,a,1,i+1),(v,b,-2,i+len(t)):x=X(q-p,c-q);y=X(q-p,t[j]-q);z=X(c-q,t[j]-q);d=sign(j*z);W[k]+=(x*y<=0)*(x*z<0 or y*z>0)*(x!=0 or d*W[k]<=0)*(y!=0 or d*W[k]>=0)*d
except:return[sum(L(A[i+1]-A[i])**.5for i in range(len(A)-1)),id(A),A]
print V(P(I,e*0,0,[e*0]*2)[2][1:-1])
ইনপুটটি ভেরিয়েবলের মাধ্যমে I
টিপলসের একটি সেট হিসাবে দেওয়া হয় ((x, y), r)
যেখানে (x, y)
বৃত্তের কেন্দ্র এবং r
এটির ব্যাসার্ধ। মানগুলি অবশ্যই float
s নয়, int
s এর হতে হবে । ফলাফলটি STDOUT এ মুদ্রিত হয়।
উদাহরণ
# First test case
I={((32.,42.),64.),((112.,99.),59.),((141.,171.),34.),((157.,191.),28.),((177.,187.),35.),((244.,168.),57.),((289.,119.),20.),((299.,112.),27.),((354.,59.),58.),((402.,98.),23.),((429.,96.),29.),((424.,145.),34.),((435.,146.),20.),((455.,204.),57.),((430.,283.),37.),((432.,306.),48.),((445.,349.),52.),((424.,409.),59.),((507.,468.),64.)}
[[ 0. 0. ]
[ 154.58723733 139.8329183 ]
[ 169.69950891 152.76985495]
[ 188.7391093 154.02738541]
[ 325.90536774 109.74141936]
[ 382.19108518 109.68789517]
[ 400.00362897 120.91319495]
[ 511. 511. ]]