가장 작은 원을 골프!


29

문제 :

데카르트 평면에 비어 있지 않은 점이 있으면 점을 모두 묶는 가장 작은 원을 찾으십시오 ( Wikipedia link ).

점 개수가 3 개 이하인 경우이 문제는 사소한 문제입니다 (한 점이있는 경우 원의 반지름이 0입니다. 두 점이있는 경우 점을 결합하는 선분은 원의 지름입니다. 세 개의 (비선형) 점을 사용하면 모호하지 않은 삼각형을 형성하면 모든 점에 닿는 원의 방정식을 얻을 수 있습니다. 따라서이 문제를 해결하려면 점수가 3보다 커야합니다.

도전 과제 :

  • 입력 : 4 개 이상의 비선형 점 목록. 점은 X와 Y 좌표를 가져야합니다. 좌표는 수 레일 수 있습니다. 문제를 해결하기 위해 두 점이 동일한 X 좌표를 공유해서는 안됩니다.
    예를 들면 다음과 같습니다.[(0,0), (2,1), (5,3), (-1,-1)]
  • 출력 : ( x h ) 2 + ( y k ) 2 = r 2(h,k,r) 와 같은 값의 튜플은 모든 점을 묶는 가장 작은 원의 방정식입니다.(xh)2+(yk)2=r2

규칙 :

  • 프로그램에 적합한 입력 방법을 선택할 수 있습니다.
  • 출력은 STDOUT함수에 인쇄 되거나 함수에 의해 반환 되어야합니다 .
  • "일반", 범용 언어가 선호되지만 모든 esolang이 허용됩니다.
  • 점이 동일 선상에 있지 않다고 가정 할 수 있습니다.
  • 이것은 코드 골프이므로 바이트 단위의 가장 작은 프로그램이 승리합니다. 당첨자는 챌린지 게시 후 1 주일 후에 선정됩니다.
    • 답변의 첫 번째 줄에 사용한 언어와 길이를 바이트 단위로 헤더로 입력하십시오. # 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]
  • 삼:
    • 입력: [(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
"동일한 비선형 포인트가 3 개있는 경우 모든 점에 닿는 원의 방정식을 얻을 수 있습니다."-가장 작은 둘러싸는 원이 아닐 수 있습니다. 둔각 삼각형의 세 꼭지점의 경우 가장 작은 둘러싸는 원은 지름이 가장 긴 변입니다.
Anders Kaseorg

2
@Arnauld 당신과 동일합니다. 테스트 사례 2의 경우 중심 (-1.73, 0.58)과 테스트 사례 3 (5.5, -4)을 얻습니다.
로빈 라이더

귀하의 의견에 감사드립니다. 이에 따라 게시물을 편집했습니다
Barranka

@Arnauld 죄송합니다. 과연. Aldo, 관찰 내용 수정
랑카

답변:


26

Wolfram Language (Mathematica) , 28 27 바이트

#~BoundingRegion~"MinDisk"&

온라인으로 사용해보십시오!

내장 기능이 여기에 편리합니다. 출력은 중심과 반경을 가진 디스크 객체입니다. 다른 사람들과 마찬가지로, 두 번째와 세 번째 테스트 사례는 질문과 다릅니다.

바이트를 저장해 준 @lirtosiast에게 감사합니다!

목록이 출력으로 필요한 경우 35 바이트 (추가 8 바이트 비용)로 수행 할 수 있습니다 . 이것을 지적 해준 @Roman에게 감사한다.


3
나는 Mathematica 내장을 기대하고있었습니다. 그러나 Mathematica에 "디스크 객체"가있을 것으로 기대하지는 않았습니다.
로빈 라이더

출력 형식을 올바르게 얻으려면 36 바이트 :Append@@BoundingRegion[#,"MinDisk"]&
Roman

20

자바 스크립트 (ES6),  298 ...  243242 바이트

배열을 반환합니다 [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) 직경 인 B를 .AB

X=Ax+Bx2,Y=Ay+By2,r=(AxBx2)2+(AyBy2)2

별개의 점 (A,B,C) 의 각 삼중 항에 대해 , 삼각형 A B C 를 둘러싸는 원 (X,Y,r) 을 생성합니다 .ABC

d=Ax(ByCy)+Bx(CyAy)+Cx(AyBy)
X=(Ax2+Ay2)(ByCy)+(Bx2+By2)(CyAy)+(Cx2+Cy2)(AyBy)2d
Y=(Ax2+Ay2)(CxBx)+(Bx2+By2)(AxCx)+(Cx2+Cy2)(BxAx)2d
r=(XAx)2+(YAy)2

생성 된 각 원에 대해 각 점 (x,y) 이 그 안에 포함되어 있는지 테스트합니다 .

(xX)2+(yY)2r

그리고 우리는 결국 가장 작은 유효 원을 반환합니다.

이행

(X,Y)d0q=Cx2+Cy2

X=(Ax2+Ay2q)(ByCy)+(Bx2+By2q)(CyAy)2d
Y=(Ax2+Ay2q)(CxBx)+(Bx2+By2q)(AxCx)2d

F(j,k)

  • (ByCy,CyAy)X
  • (CxBx,AxCx)Y

Fs(X,Y)d=0


아마도 뉴턴 타입의 수치 최적화를 작성하는 것이 더 짧을 것입니다 ...
qwr

정확성에 대한 증거가 있습니까? 나는 이것이 그럴듯한 접근법이라는 것을 알 수 있지만, 그보다 더 많은 작업이 필요한 것 같습니다.
피터 테일러

3
@PeterTaylor이 알고리즘은 Wikipedia에 언급되어 있습니다. 순진한 알고리즘은 모든 쌍과 점의 트리플로 결정된 원을 테스트하여 시간 O (n ^ 4)의 문제를 해결합니다 . 그러나 불행히도 증명에 대한 링크는 없습니다.
Arnauld

해결책이없는 정밀성 문제를 충족시킬 수 있습니까?
l4m2

1
@Arnauld 만약 당신이 도달하기 위해 이상한 숫자가 필요하다면, 나는 괜찮습니다. 쉬운 상황에서도 문제가 될 수있는 경우
l4m2

14

R , 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ñ/$Ʋ€$ñ_ƭƒⱮṀ¥Ðḟ⁸ṚÞḢ

온라인으로 사용해보십시오!

내 Wolfram 언어 답변 과 달리 Jelly는 이것을 달성하기 위해 많은 코드가 필요합니다 (내가 뭔가를 빠뜨리지 않는 한)! 이 전체 프로그램은 점 목록을 인수로 사용하여 가장 작은 둘러싸는 원의 중심과 반지름을 반환합니다. 세 점의 모든 세트에 대해 원주를 생성하고 두 점의 모든 세트에 대한 직경을 생성하고 모든 점을 포함하는지 확인한 다음 반지름이 가장 작은 것을 선택합니다.

make_circumcircle 비트의 코드는 이 사이트의 코드에서 영감을 얻은 후 Wikipedia에서 영감을 얻은 것입니다.


1
이 코드를 이해하지 못하지만 직경과 원이 아닌 개별적으로 세 개의 점 세트를 복제하여 생성하고 세 개의 동일한 점의 목록을 필터링 할 수 있습니까?
lirtosiast

2

APL (NARS), 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⍵}

이것은 Arnauld 솔루션에서 수식의 '구현'중 하나입니다 ... 결과 및 의견 :

  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 : 오메가 세트에서 알파 젯의 조합을 찾습니다.

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

이제부터 ((X, Y), r)은 (XY)에서 반경 r과 중심의 한 원주를 나타냅니다.

c : ⍺의 점이 ⍵의 원주 ((XY) r) 내에 있는지 확인 (결과 <= 0) ot 외부 (결과> 0)의 원주 입력의 경우 ⍬는 입력으로, 가능한 모든 입력을 ⍺에 1 (둘레 밖)로 반환합니다.

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

p : 만약 ⍵가 ((XY) r)의 배열이면; 배열 ⍺의 모든 점이 ((XY) r의 내부에 있으면 points의 ((XY) r) 각각에 대해 1을 쓰고 그렇지 않으면 0 NB를 씁니다. epsilon = 1e¯으로 반올림했기 때문에 가지 않는 것이 있습니다 13. 다시 말해서 평면의 포인트 (아마도 목적에 따라 구축 된)의 경우는 100 % 해결책이 아닙니다.

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

s2 : ⍵의 2 포인트에서 원주를 2 포인트의 지름을 갖는 형식 ((XY) r)으로 반환합니다.

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

s3 : 3 점에서 3 점을 통과하는 형식 ((XY) r)으로 원주를 반환합니다. 문제 (예 : 점이 정렬 됨)가 있으면 실패하고 fail을 반환합니다.

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가 찾은 점 또는 n 점을 모두 포함하는 s3 유형의 원주를 찾습니다.

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

s1 : 위의 s에서 찾은 집합에서 최소 반지름을 가진 집합을 계산하고 최소 반지름을 가진 첫 번째 집합을 반환합니다. 세 숫자는 배열입니다 (첫 번째 및 두 번째 좌표는 중심의 좌표이고 세 번째 숫자는 둘레의 반경입니다).

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에 오신 것을 환영합니다! Python 2를 사용하고 있으므로 5 행의 두 공백을 탭으로 변환하여 1 바이트를 절약 할 수 있습니다.
스티븐

P={x+y*1j for x,y in input()}2 바이트도 저장합니다.
Mr. Xcoder

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]많은 공백을 절약 할 수 있습니다 . 나는 당신이 미리 d를 초기화 할 필요가 없다고 생각합니다. 또한 두 개의 변수를 사용 E,F=e,f하고 라인 10 print에서 훨씬 짧아 질 것입니다. 나는 max목록 이해력이 있는 솔루션 이 두 개의 루프보다 짧을 것이라고 생각 하지만 잘못되었을 수 있습니다. 그러나 안타깝게도 솔루션이 올바르지 않습니다. 점 (-1,0), (0,1.41), (0.5, 0), (1,0)의 경우 솔루션은 반지름 1을 사용하여 0 주위의 원을 계산하지만 (1, 1.41) 점은 그렇지 않습니다 원.
블랙 올빼미 카이

환영! 답변 주셔서 감사합니다. 위의 의견에서 지적했듯이 솔루션이 올바르지 않습니다. 무차별 대입 솔루션에 대한 힌트 : 가능한 가장 작은 원이 두 점 또는 세 점에 닿습니다. 각 점 쌍에 닿는 ​​원의 방정식 계산을 시작하고 모든 점을 포함하는 원이 있는지 확인할 수 있습니다. 그런 다음 점의 각 삼중 항에 닿는 원의 방정식을 계산하고 모든 점을 포함하는 원이 있는지 확인하십시오. 가능한 모든 원을 얻으면 가장 작은 반지름을 가진 원을 선택하십시오.
Barranka

1
좋아, 나는 그것을 작동 시키려고 노력하고 나서 대답을 업데이트 할 것이다. 점이 원에 포함되어 있는지 확인하는 방법을 알아야합니다.
벤 모리슨

원의 중심과 반경이 있으면 중심과 각 점 사이의 거리가 반경보다 작거나 같은지 확인하십시오. 해당 조건이 모든 포인트에 해당되는 경우 해당 원은 후보입니다
Barranka
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.