Golf the smallest circle!
Wolfram Language (Mathematica), 28 27 bytes
#~BoundingRegion~"MinDisk"&
Try it online!
Built-ins are handy here. Output is a disk object with the centre and radius. Like others, I’ve found the 2nd and 3rd test cases to be different to the question.
Thanks to @lirtosiast for saving a byte!
If a list is required as output, this can be done in 35 bytes (at the cost of an additional 8 bytes). Thanks to @Roman for pointing this out.
JavaScript (ES6), 298 ... 243 242 bytes
Returns an array [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
Try it online!
or see a formatted version
How?
Method
For each pair of points \$(A,B)\$, we generate the circle \$(X,Y,r)\$ whose diameter is \$AB\$.
$$X=\frac{A_x+B_x}{2},\;Y=\frac{A_y+B_y}{2},\;r=\sqrt{\left(\frac{A_x-B_x}{2}\right)^2+\left(\frac{A_y-B_y}{2}\right)^2}$$
For each triple of distinct points \$(A,B,C)\$, we generate the circle \$(X,Y,r)\$ which circumscribes the triangle \$ABC\$.
$$d=A_x(B_y-C_y)+B_x(C_y-A_y)+C_x(A_y-B_y)$$ $$X=\frac{({A_x}^2+{A_y}^2)(B_y-C_y)+({B_x}^2+{B_y}^2)(C_y-A_y)+({C_x}^2+{C_y}^2)(A_y-B_y)}{2d}$$ $$Y=\frac{({A_x}^2+{A_y}^2)(C_x-B_x)+({B_x}^2+{B_y}^2)(A_x-C_x)+({C_x}^2+{C_y}^2)(B_x-A_x)}{2d}$$ $$r=\sqrt{(X-A_x)^2+(Y-A_y)^2}$$
For each generated circle, we test whether each point \$(x,y)\$ is enclosed within it:
$$\sqrt{(x-X)^2+(y-Y)^2}\le r$$
And we eventually return the smallest valid circle.
Implementation
In the JS code, the formula to compute \$(X,Y)\$ for the triangle's circumscribed circle is slightly simplified. Assuming \$d\neq0\$, we define \$q={C_x}^2+{C_y}^2\$, leading to:
$$X=\frac{({A_x}^2+{A_y}^2-q)(B_y-C_y)+({B_x}^2+{B_y}^2-q)(C_y-A_y)}{2d}$$ $$Y=\frac{({A_x}^2+{A_y}^2-q)(C_x-B_x)+({B_x}^2+{B_y}^2-q)(A_x-C_x)}{2d}$$
This way, the helper function \$F\$ requires only two parameters \$(j,k)\$ to compute each coordinate:
- \$(B_y-C_y,\;C_y-A_y)\$ for \$X\$
- \$(C_x-B_x,\;A_x-C_x)\$ for \$Y\$
The third parameter used in \$F\$ (i.e. its actual argument \$s\$) is used to compute \$(X,Y)\$ when \$d=0\$, meaning that the triangle is degenerate and we have to try to use the diameter instead.
R, 59 bytes
function(x)nlm(function(y)max(Mod(x-y%*%c(1,1i))),0:1)[1:2]
Try it online!
Takes input as a vector of complex coordinates. Mod
is the distance (modulus) in the complex plane and nlm
is an optimization function: it finds the position of the center (output as estimate
) which minimizes the maximum distance to the input points, and gives the corresponding distance (output as minimum
), i.e. the radius. Accurate to 3-6 digits; the TIO footer rounds the output to 2 digits.
nlm
takes a numeric vector as input: the y%*%c(1,1i)
business converts it to a complex.