गोल्फ सबसे छोटा सर्कल!


29

समस्या:

कार्टेशियन विमान में बिंदुओं के एक गैर-खाली सेट को देखते हुए, सबसे छोटा वृत्त खोजें जो उन सभी को जोड़ता है ( विकिपीडिया लिंक )।

यह समस्या तुच्छ है यदि अंकों की संख्या तीन या उससे कम है (यदि एक बिंदु है, तो सर्कल में शून्य का त्रिज्या है; यदि दो बिंदु हैं, तो बिंदुओं को जोड़ने वाला रेखा खंड सर्कल का व्यास है; यदि वहां हैं तीन (नॉन-कॉलिनियर) अंक, एक सर्कल के समीकरण को प्राप्त करना संभव है जो उन सभी को छूता है यदि वे एक गैर-ऑब्सट्यूज़ त्रिकोण बनाते हैं, या एक सर्कल जो केवल दो बिंदुओं को छूता है और तीसरे को संलग्न करता है यदि त्रिकोण ऑब्सट्यूट है)। इसलिए, इस चुनौती के लिए, अंकों की संख्या तीन से अधिक होनी चाहिए।

चुनौती:

  • इनपुट: 4 या अधिक गैर-कॉलिनियर बिंदुओं की सूची। अंक में X और Y निर्देशांक होना चाहिए; निर्देशांक फ्लोट हो सकते हैं। चुनौती को कम करने के लिए, किसी भी दो बिंदुओं को समान X समन्वय नहीं करना चाहिए।
    उदाहरण के लिए:[(0,0), (2,1), (5,3), (-1,-1)]
  • आउटपुट: मानों का एक समूह (h,k,r), जैसे कि (एक्स-)2+(y-कश्मीर)2=आर2 सभी बिंदुओं को घेरने वाले सबसे छोटे वृत्त का समीकरण है।

नियम:

  • आप जो भी इनपुट मेथड अपना प्रोग्राम सूट करते हैं उसे चुन सकते हैं।
  • आउटपुट को STDOUTकिसी फ़ंक्शन द्वारा मुद्रित या लौटाया जाना चाहिए ।
  • "सामान्य", सामान्य-उद्देश्य, भाषाएं पसंद की जाती हैं, लेकिन कोई भी एसोलैंग स्वीकार्य है।
  • आप मान सकते हैं कि अंक कॉलिनियर नहीं हैं।
  • यह कोड-गोल्फ है, इसलिए बाइट्स में सबसे छोटा कार्यक्रम जीत जाता है। चुनौती पोस्ट किए जाने के एक सप्ताह बाद विजेता का चयन किया जाएगा।
    • कृपया अपने उत्तर की पहली पंक्ति में हेडर के रूप में आपके द्वारा उपयोग की जाने वाली भाषा और बाइट में लंबाई शामिल करें: # Language: n bytes

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

  • 1:
    • इनपुट: [(-8,0), (3,1), (-6.2,-8), (3,9.5)]
    • आउटपुट: [-1.6, 0.75, 9.89]
  • 2:
    • इनपुट: [(7.1,-6.9), (-7,-9), (5,10), (-9.5,-8)]
    • आउटपुट: [-1.73, 0.58, 11.58]
  • 3:
    • इनपुट: [(0,0), (1,2), (3,-4), (4,-5), (10,-10)]
    • आउटपुट: [5.5, -4, 7.5]
  • 4:
    • इनपुट: [(6,6), (-6,7), (-7,-6), (6,-8)]
    • आउटपुट: [0, -0.5, 9.60]

हैप्पी गोल्फिंग !!!


संबंधित चुनौती:



8
"अगर तीन (नॉन को-लीनियर) पॉइंट्स हैं, तो एक सर्कल के समीकरण को प्राप्त करना संभव है जो उन सभी को छूता है" -लेकिन वह सबसे छोटा एनक्लोजिंग सर्कल नहीं हो सकता है। एक तिरछे त्रिभुज के तीन कोने के लिए, सबसे छोटा घेरना वृत्त वह होता है जिसका व्यास सबसे लंबा होता है।
एंडर्स कासोर्ग

2
@Arnauld आप के रूप में ही। टेस्ट केस 2 के लिए, मुझे केंद्र (-1.73, 0.58) और टेस्ट केस 3 (5.5, -4) के लिए मिलता है।
रॉबिन राइडर

@ आपकी टिप्पणी के लिए धन्यवाद। मैंने तदनुसार पोस्ट संपादित की है
बैरनका

@Arnauld ओह, माफ करना। वास्तव में। एल्डो, आपकी टिप्पणियों के साथ सही
बारांका

जवाबों:


26

Wolfram भाषा (Mathematica) , 28 27 बाइट्स

#~BoundingRegion~"MinDisk"&

इसे ऑनलाइन आज़माएं!

बिल्ट-इन यहाँ काम कर रहे हैं। आउटपुट केंद्र और त्रिज्या के साथ एक डिस्क ऑब्जेक्ट है। दूसरों की तरह, मैंने 2 और 3 के परीक्षण मामलों को प्रश्न से अलग पाया है।

एक बाइट को बचाने के लिए @lirtosiast को धन्यवाद!

यदि एक सूची आउटपुट के रूप में आवश्यक है, तो यह 35 बाइट्स (अतिरिक्त 8 बाइट्स की लागत पर) में किया जा सकता है । इसे इंगित करने के लिए @ रमन का धन्यवाद।


3
मैं एक गणितज्ञ निर्मित में उम्मीद कर रहा था। लेकिन मैं "डिस्क ऑब्जेक्ट्स" के लिए गणितज्ञ की उम्मीद नहीं कर रहा था।
रॉबिन राइडर

आउटपुट प्रारूप सही पाने के लिए 36 बाइट्स :Append@@BoundingRegion[#,"MinDisk"]&
रोमन

20

जावास्क्रिप्ट (ईएस 6),  298 ... 243  242 बाइट्स

एक सरणी देता है [x, y, r]

p=>p.map(m=([c,C])=>p.map(([b,B])=>p.map(([a,A])=>p.some(([x,y])=>H(x-X,y-Y)>r,F=s=>Y=(d?((a*a+A*A-q)*j+(b*b+B*B-q)*k)/d:s)/2,d=c*(A-B)+a*(j=B-C)+b*(k=C-A),r=H(a-F(a+b),A-F(A+B,X=Y,j=c-b,k=a-c)))|r>m?0:o=[X,Y,m=r]),q=c*c+C*C),H=Math.hypot)&&o

इसे ऑनलाइन आज़माएं!

या स्वरूपित संस्करण देखें

कैसे?

तरीका

(A,B)(X,Y,r)AB

X=एक्स+बीएक्स2,Y=y+बीy2,आर=(एक्स-बीएक्स2)2+(y-बीy2)2

(,बी,सी)(एक्स,Y,आर)बीसी

=एक्स(बीy-सीy)+बीएक्स(सीy-y)+सीएक्स(y-बीy)
एक्स=(एक्स2+y2)(बीy-सीy)+(बीएक्स2+बीy2)(सीy-y)+(सीएक्स2+सीy2)(y-बीy)2
Y=(एक्स2+y2)(सीएक्स-बीएक्स)+(बीएक्स2+बीy2)(एक्स-सीएक्स)+(सीएक्स2+सीy2)(बीएक्स-एक्स)2
आर=(एक्स-एक्स)2+(Y-y)2

(एक्स,y)

(एक्स-एक्स)2+(y-Y)2आर

और हम अंततः सबसे छोटे वैध सर्कल को वापस करते हैं।

कार्यान्वयन

(एक्स,Y)0क्ष=सीएक्स2+सीy2

एक्स=(एक्स2+y2-क्ष)(बीy-सीy)+(बीएक्स2+बीy2-क्ष)(सीy-y)2
Y=(एक्स2+y2-क्ष)(सीएक्स-बीएक्स)+(बीएक्स2+बीy2-क्ष)(एक्स-सीएक्स)2

एफ(j,कश्मीर)

  • (बीy-सीy,सीy-y)एक्स
  • (सीएक्स-बीएक्स,एक्स-सीएक्स)Y

एफरों(एक्स,Y)=0


शायद न्यूटन-टाइप न्यूमेरिकल ऑप्टिमाइज़र लिखना कम है ...
qwr

क्या आपके पास शुद्धता का प्रमाण है? मैं देख सकता हूं कि यह एक प्रशंसनीय दृष्टिकोण है, लेकिन इससे कहीं अधिक के लिए काफी काम करने की आवश्यकता है।
पीटर टेलर

3
@PeterTaylor एल्गोरिथ्म का उल्लेख विकिपीडिया पर किया गया है: एक भोली एल्गोरिथ्म समय की समस्या को हल करता है O (n ^ 4) में सभी जोड़ियों और त्रिभुज द्वारा निर्धारित हलकों का परीक्षण किया जाता है । लेकिन दुर्भाग्य से, एक सबूत के लिए कोई लिंक नहीं है।
अरनुलद

क्या यह बिना किसी समाधान के सटीक बनाने की समस्या को पूरा करेगा?
l4m2

1
@ अरनल्ड यदि आपको पहुँचने के लिए कुछ अजीब संख्याओं की आवश्यकता है, तो मैं कह सकता हूँ कि यह ठीक है; यदि यह आसान स्थिति में भी विफल हो जाता है जो एक समस्या हो सकती है
l4m2

14

आर , 59 बाइट्स

function(x)nlm(function(y)max(Mod(x-y%*%c(1,1i))),0:1)[1:2]

इसे ऑनलाइन आज़माएं!

जटिल निर्देशांक के एक वेक्टर के रूप में इनपुट लेता है। Modजटिल विमान में दूरी (मापांक) है और nlmएक अनुकूलन कार्य है: यह केंद्र की स्थिति (आउटपुट estimate) के रूप में पाता है जो इनपुट बिंदुओं की अधिकतम दूरी को कम करता है, और इसी दूरी (आउटपुट के रूप में minimum), यानी त्रिज्या देता है। । 3-6 अंकों का सटीक; TIO पाद लेख आउटपुट को 2 अंको तक पहुंचाता है।

nlmएक संख्यात्मक वेक्टर को इनपुट के रूप में लेता है: y%*%c(1,1i)व्यवसाय इसे एक जटिल में परिवर्तित करता है।


9

जेली , 100 98 बाइट्स

_²§½
1ịṭƊZIṚṙ€1N1¦,@ṭ@²§$µḢZḢ×Ø1œị$SḤ÷@P§
ZṀ+ṂHƲ€_@Ç+ḷʋ⁸,_²§½ʋḢ¥¥
œc3Ç€;ŒcZÆm,Hñ/$Ʋ€$ñ_ƭƒⱮṀ¥Ðḟ⁸ṚÞḢ

इसे ऑनलाइन आज़माएं!

मेरे वुल्फराम भाषा के उत्तर के विपरीत , जेली को इसे प्राप्त करने के लिए कोड की बहुत आवश्यकता है (जब तक कि मैं कुछ याद नहीं कर रहा हूँ!)। यह पूरा कार्यक्रम अपने तर्क के रूप में बिंदुओं की सूची लेता है और सबसे छोटे संलग्न सर्कल के केंद्र और त्रिज्या को वापस करता है। यह तीन बिंदुओं के सभी सेटों के लिए खतना बनाता है, और दो बिंदुओं के सभी सेटों के लिए डायमीटर, चेक जिसमें सभी बिंदु शामिल होते हैं और फिर सबसे छोटे त्रिज्या वाले को चुनता है।

इस साइट पर कोड द्वारा make_circumcircle बिट के लिए कोड बदले में विकिपीडिया से प्रेरित था।


1
मुझे यह कोड समझ में नहीं आता है, बल्कि अलग-अलग व्यास और खतना के बजाय, क्या आप तीन बिंदुओं के सभी सेट डुप्लिकेट के साथ उत्पन्न कर सकते हैं और तीन समान बिंदुओं की सूची को फ़िल्टर कर सकते हैं?
lirtosiast

2

एपीएल (एनएआरएस), 348 चार्ट, 696 बाइट्स

f←{h←{0=k←⍺-1:,¨⍵⋄(k<0)∨k≥i←≢w←⍵:⍬⋄↑,/{w[⍵],¨k h w[(⍳i)∼⍳⍵]}¨⍳i-k}⋄1≥≡⍵:⍺h⍵⋄⍺h⊂¨⍵}
c←{⍵≡⍬:1⋄(x r)←⍵⋄(-r*2)++/2*⍨⍺-x}
p←{(b k)←⍺ ⍵⋄∧/¨1e¯13≥{{⍵{⍵c⍺}¨b}k[⍵]}¨⍳≢k}
s2←{(+/k),√+/↑2*⍨-/k←2÷⍨⍵}
s3←{0=d←2×-.×m←⊃{⍵,1}¨⍵:⍬⋄m[;1]←{+/2*⍨⍵}¨⍵⋄x←d÷⍨-.×m⋄m[;2]←{1⊃⍵}¨⍵⋄y←d÷⍨--.×m⋄(⊂x y),√+/2*⍨(x y)-1⊃⍵}
s←{v/⍨⍵p v←(s2¨2 f⍵)∪s3¨3 f⍵}
s1←{↑v/⍨sn=⌊/sn←{2⊃⍵}¨v←s⍵}

यह अरनुल्ल समाधान में सूत्रों का एक 'कार्यान्वयन' है ... परिणाम और टिप्पणियां:

  s1 (¯8 0)(3 1)(¯6.2 ¯8)(3 9.5)
¯1.6 0.75  9.885469134 
  s1 (7.1 ¯6.9)(¯7 ¯9)(5 10)(¯9.5 ¯8)
¯1.732305109 0.5829680042  11.57602798 
  s1 (0 0)(1 2)(3 ¯4)(4 ¯5)(10 ¯10)
5.5 ¯4  7.5 
  s1 (6 6)(¯6 7)(¯7 ¯6)(6 ¯8)
0 ¯0.5  9.604686356 
  s1 (6 6)(¯6 7)(¯7 ¯6)(6 ¯8)(0 0)(1 2)(3 ¯4)(4 ¯5)(10 ¯10)
2 ¯1.5  11.67261753 
  s1 (6 6)(¯6 7)(¯7 ¯6)(6 ¯8)(1 2)(3 ¯4)(4 ¯5)(10 ¯10)(7.1 ¯6.9)(¯7 ¯9)(5 10)(¯9.5 ¯8)
1.006578947 ¯1.623355263  12.29023186 
  s1 (1 1)(2 2)(3 3)(4 4)
2.5 2.5  2.121320344 
  ⎕fmt s3 (1 1)(2 2)(3 3)(4 4)
┌0─┐
│ 0│
└~─┘

एफ: ओमेगा सेट में अल्फा ओजेट्स के संयोजन को पाता है

f←{h←{0=k←⍺-1:,¨⍵⋄(k<0)∨k≥i←≢w←⍵:⍬⋄↑,/{w[⍵],¨k h w[(⍳i)∼⍳⍵]}¨⍳i-k}⋄1≥≡⍵:⍺h⍵⋄⍺h⊂¨⍵}

((X, Y), r) अब से त्रिज्या r और केंद्र (XY) के एक circonference का प्रतिनिधित्व करते हैं।

c: यह पाता है कि point में बिंदु परिधि ((XY) r) के अंदर है ⍵ (परिणाम <= 0) ot यह बाहरी है (परिणाम> 0) in में परिधि इनपुट के मामले में यह, इनपुट के रूप में है, यह would (परिधि से बाहर) input में प्रत्येक संभावित इनपुट लौटाएगा।

c←{⍵≡⍬:1⋄(x r)←⍵⋄(-r*2)++/2*⍨⍺-x}

p: यदि) (XY) r का एक सरणी है; each (XY) r में से प्रत्येक के लिए if 1 लिखता है अगर सरणी में सभी बिंदु ⍺ ((XY) r) के आंतरिक हैं, अन्यथा 0 NB लिखता है यहां कुछ ऐसा है जो इसलिए नहीं जाता है क्योंकि मुझे epsilon = 1¯ के लिए गोल करना था 13। दूसरे शब्दों में विमान में बिंदुओं की सीमा के मामलों में (और शायद उद्देश्य पर निर्मित) यह 100% बीमाकृत समाधान नहीं है

p←{(b k)←⍺ ⍵⋄∧/¨1e¯13≥{{⍵{⍵c⍺}¨b}k[⍵]}¨⍳≢k}

s2: 2 में 2-बिंदु से, यह प्रारूप में परिधि लौटाता है ((XY) r) जिसमें उन 2 बिंदुओं का व्यास है

s2←{(+/k),√+/↑2*⍨-/k←2÷⍨⍵}

s3: 3 बिंदुओं से, यह उन तीन बिंदुओं से गुजरने वाले प्रारूप ((XY) r) में परिधि लौटाता है यदि समस्याएँ हैं (उदाहरण के लिए अंक संरेखित हैं), तो यह विफल हो जाएगी और points वापस आ जाएगी।

s3←{0=d←2×-.×m←⊃{⍵,1}¨⍵:⍬⋄m[;1]←{+/2*⍨⍵}¨⍵⋄x←d÷⍨-.×m⋄m[;2]←{1⊃⍵}¨⍵⋄y←d÷⍨--.×m⋄(⊂x y),√+/2*⍨(x y)-1⊃⍵}

ध्यान दें कि - × मैट्रिक्स nxn के निर्धारक को खोजें और

  ⎕fmt ⊃{⍵,1}¨(¯8 0)(3 1)(¯6.2 ¯8)
┌3─────────┐     
3 ¯8    0 1│     |ax  ay 1|
│  3    1 1│   d=|bx  by 1|=ax(by-cy)-bx(ay-cy)+cx(ay-by)=ax(by-cy)+bx(cy-ay)+cx(ay-by)
│ ¯6.2 ¯8 1│     |cx  cy 1|
└~─────────┘

s: n बिंदुओं से ⍵ में, यह s2 द्वारा पाए गए उन प्रकारों के प्रकारों को या उन s3 के प्रकारों को खोजता है जिनमें सभी n अंक होते हैं।

s←{v/⍨⍵p v←(s2¨2 f⍵)∪s3¨3 f⍵}

s1: ऊपर से पाए गए सेट से उन लोगों की गणना होती है जिनके पास न्यूनतम त्रिज्या होती है और पहले वाले को न्यूनतम त्रिज्या देता है। सरणियों के रूप में तीन नंबर (पहला और दूसरा निर्देशांक केंद्र के निर्देशांक हैं, जबकि तीसरा परिधि की त्रिज्या है)।

s1←{↑v/⍨sn=⌊/sn←{2⊃⍵}¨v←s⍵}

2

पायथन 2 (PyPy) , 244 242 बाइट्स

P={complex(*p)for p in input()}
Z=9e999,
for p in P:
 for q in{p}^P:
	for r in{p}^P:R,S=1j*(p-q),q-r;C=S.imag and S.real/S.imag-1jor 1;c=(p+q-(S and(C*(p-r)).real/(C*R).real*R))/2;Z=min(Z,(max(abs(c-t)for t in P),c.imag,c.real))
print Z[::-1]

इसे ऑनलाइन आज़माएं!

यह जानवर-बल O (n ^ 4) एल्गोरिथ्म का उपयोग करता है, प्रत्येक जोड़ी और बिंदुओं के त्रिकोण के माध्यम से पुनरावृत्ति करता है, केंद्र की गणना करता है, और केंद्र को रखता है जिसे सभी बिंदुओं को संलग्न करने के लिए सबसे छोटी त्रिज्या की आवश्यकता होती है। यह दो लंबवत द्विभाजक के चौराहे को खोजने के माध्यम से 3 बिंदुओं की परिधि की गणना करता है (या, यदि दो अंक बराबर हैं तो यह तीसरे के साथ मध्य बिंदु का उपयोग करता है)।


PPCG में आपका स्वागत है! चूंकि आप पायथन 2 का उपयोग कर रहे हैं, तो आप 5 स्थानों को 5 पंक्ति में एक टैब में परिवर्तित करके 1 बाइट बचा सकते हैं।
स्टीफन

P={x+y*1j for x,y in input()}साथ ही 2 बाइट्स बचाता है।
श्री एक्सकोडर

1

पायथन 212 190 बाइट्स

यह समाधान गलत है, और मुझे अभी काम करना है इसलिए मेरे पास इसे ठीक करने का समय नहीं है।

a=eval(input())
b=lambda a,b: ((a[0]-b[0])**2+(a[1]-b[1])**2)**.5
c=0
d=1
for e in a:
    for f in a:
        g=b(e,f)
        if g>c:
            c=g
            d=[e,f]
print(((d[0][0]+d[1][0])/2,(d[0][1]+d[1][1])/2,c/2))

इसे ऑनलाइन आज़माएं!

मुझे पता चला कि कौन से दो अंक सबसे दूर हैं और फिर मैंने उन बिंदुओं के आधार पर एक सर्कल के लिए एक समीकरण उत्पन्न किया!

मुझे पता है कि यह अजगर में सबसे छोटा नहीं है, लेकिन यह सबसे अच्छा मैं कर सकता हूं! इसके अलावा, यह इनमें से एक करने का मेरा पहला प्रयास है, इसलिए कृपया समझें!


2
यह कुछ और गोल्फ हो सकता है। उदाहरण के लिए, आप छोटा कर सकते हैं if g>c:\n c=g\n d=[e,f]करने के लिए if g>c:c=g;d=[e,f], आप सफेद स्थान का एक बहुत बचत होगी। मुझे नहीं लगता कि आपको पहले से डी को इनिशियलाइज़ करने की ज़रूरत है, दो वैरिएबल और E,F=e,fलाइन 10 का उपयोग करने से भी आप printबहुत कम हो जाएंगे । मुझे लगता है कि एक समाधान maxऔर एक सूची की समझ दो छोरों से भी छोटी होगी, लेकिन मैं गलत हो सकता हूं। अफसोस की बात है, हालांकि, आपका समाधान सही नहीं है। अंकों (-1,0), (0,1.41), (0.5, 0), (1,0) के लिए आपका समाधान 0 के आसपास एक वृत्त की त्रिज्या के साथ गणना करता है। 1. लेकिन बिंदु (1, 1.41) उस में नहीं है वृत्त।
काले उल्लू काई

स्वागत हे! आपके उत्तर के लिए धन्यवाद। जैसा कि ऊपर टिप्पणी में बताया गया है, आपका समाधान सही नहीं है। जानवर-बल समाधान के लिए एक संकेत: सबसे छोटा संभव चक्र या तो दो अंक या तीन बिंदुओं को छूता है। आप उस सर्कल के लिए समीकरण की गणना शुरू कर सकते हैं जो प्रत्येक जोड़ी को छूता है और जांचें कि क्या कोई ऐसा है जो सभी बिंदुओं को जोड़ता है। फिर सर्कल के लिए समीकरण की गणना करें जो प्रत्येक त्रिकोणीय बिंदुओं को छूता है और जांचें कि क्या कोई ऐसा है जो सभी बिंदुओं को संलग्न करता है। एक बार जब आप सभी संभव सर्कल प्राप्त कर लेते हैं, तो सबसे छोटे त्रिज्या वाले को चुनें।
बैरनका

1
ठीक है मैं इसे काम करने की कोशिश करने जा रहा हूं, और फिर मैं जवाब को अपडेट करूंगा। मुझे यह पता लगाने की आवश्यकता है कि किसी बिंदु को एक सर्कल में समाहित किया गया है या नहीं।
बेन मॉरिसन

एक बार जब आपके पास सर्कल का केंद्र और त्रिज्या होता है, तो जांचें कि केंद्र और प्रत्येक बिंदु के बीच की दूरी त्रिज्या से कम या बराबर है; यदि वह शर्त सभी बिंदुओं के लिए सही है, तो वह चक्र एक उम्मीदवार है
बैरनका
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.