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.