El problema:
Dado un conjunto de puntos no vacío en el plano cartesiano, encuentre el círculo más pequeño que los encierra a todos ( enlace de Wikipedia ).
Este problema es trivial si el número de puntos es tres o menos (si hay un punto, el círculo tiene un radio de cero; si hay dos puntos, el segmento de línea que une los puntos es el diámetro del círculo; si hay tres puntos (no colineales), es posible obtener la ecuación de un círculo que los toca a todos si forman un triángulo no obtuso, o un círculo que toca solo dos puntos y encierra el tercero si el triángulo es obtuso). Entonces, por el bien de este desafío, el número de puntos debería ser mayor que tres.
El reto:
- Entrada: una lista de 4 o más puntos no colineales. Los puntos deben tener coordenadas X e Y; Las coordenadas pueden ser flotadores. Para facilitar el desafío, no hay dos puntos que compartan la misma coordenada X.
Por ejemplo:[(0,0), (2,1), (5,3), (-1,-1)]
- Salida: una tupla de valores, de
(h,k,r)
modo que es la ecuación del círculo más pequeño que encierra todos los puntos.
Reglas:
- Puede elegir el método de entrada que se adapte a su programa.
- La salida debe ser impresa
STDOUT
o devuelta por una función. - Se prefieren los idiomas "normales", de uso general, pero cualquier esolang es aceptable.
- Puede suponer que los puntos no son colineales.
- Este es el código de golf, por lo que gana el programa más pequeño en bytes. El ganador será seleccionado una semana después de que se publique el desafío.
- Incluya el idioma que utilizó y la longitud en bytes como encabezado en la primera línea de su respuesta:
# Language: n bytes
- Incluya el idioma que utilizó y la longitud en bytes como encabezado en la primera línea de su respuesta:
Casos de prueba:
- 1:
- Entrada:
[(-8,0), (3,1), (-6.2,-8), (3,9.5)]
- Salida:
[-1.6, 0.75, 9.89]
- Entrada:
- 2:
- Entrada:
[(7.1,-6.9), (-7,-9), (5,10), (-9.5,-8)]
- Salida:
[-1.73, 0.58, 11.58]
- Entrada:
- 3:
- Entrada:
[(0,0), (1,2), (3,-4), (4,-5), (10,-10)]
- Salida:
[5.5, -4, 7.5]
- Entrada:
- 4:
- Entrada:
[(6,6), (-6,7), (-7,-6), (6,-8)]
- Salida:
[0, -0.5, 9.60]
- Entrada:
¡Feliz golf!
Respuestas:
Wolfram Language (Mathematica) ,
2827 bytesPruébalo en línea!
Los empotrados son útiles aquí. La salida es un objeto de disco con el centro y el radio. Como otros, he encontrado que los casos de la segunda y tercera prueba son diferentes a la pregunta.
¡Gracias a @lirtosiast por guardar un byte!
Si se requiere una lista como salida, esto puede hacerse en 35 bytes (a costa de 8 bytes adicionales) . Gracias a @Roman por señalar esto.
fuente
Append@@BoundingRegion[#,"MinDisk"]&
JavaScript (ES6),
298 ... 243242 bytesDevuelve una matriz
[x, y, r]
.Pruébalo en línea!
o ver una versión formateada
¿Cómo?
Método
Para cada par de puntos( A , B ) , generamos el círculo ( X, Y, R ) cuyo diámetro es A B .
Para cada triple de puntos distintos( A , B , C) , que generan el círculo ( X, Y, R ) que circunscribe el triángulo UNA B C .
Y finalmente devolvemos el círculo válido más pequeño.
Implementación
fuente
R , 59 bytes
Pruébalo en línea!
Toma la entrada como un vector de coordenadas complejas.
Mod
es la distancia (módulo) en el plano complejo ynlm
es una función de optimización: encuentra la posición del centro (salida comoestimate
) que minimiza la distancia máxima a los puntos de entrada y proporciona la distancia correspondiente (salida comominimum
), es decir, el radio . Preciso de 3-6 dígitos; el pie de página TIO redondea la salida a 2 dígitos.nlm
toma un vector numérico como entrada: lay%*%c(1,1i)
empresa lo convierte en complejo.fuente
Jalea ,
10098 bytesPruébalo en línea!
En contraste con mi respuesta del lenguaje Wolfram , Jelly necesita bastante código para lograr esto (¡a menos que me falte algo!). Este programa completo toma la lista de puntos como argumento y devuelve el centro y el radio del círculo cerrado más pequeño. Genera círculos para todos los conjuntos de tres puntos y diámetros para todos los conjuntos de dos puntos, verifica los que incluyen todos los puntos y luego selecciona el que tiene el radio más pequeño.
El código para el bit make_circumcircle se inspiró en el código de este sitio , a su vez inspirado en Wikipedia.
fuente
APL (NARS), 348 caracteres, 696 bytes
Esta es una 'implementación' de fórmulas en la solución Arnauld ... Resultados y comentarios:
f: encuentra la combinación de alfa ojets en el conjunto omega
((X, Y), r) a partir de ahora representan una circunferencia de radio r y centro en (XY).
c: encuentra si el punto en ⍺ está dentro de la circunferencia ((XY) r) en ⍵ (resultado <= 0) ot es externo (resultado> 0) En el caso de entrada de circunferencia en ⍵ es ⍬ como entrada, devolvería 1 (fuera de circunferencia) cada entrada posible en ⍺.
p: si ⍵ es una matriz de ((XY) r); para cada uno de los ((XY) r) en ⍵ escribe 1 si todos los puntos en la matriz ⍺ son internos a ((XY) r) de lo contrario escribe 0 NB Aquí hay algo que no funciona porque tuve que redondear a epsilon = 1e¯ 13) en otras palabras, en casos límite de puntos en el plano (y probablemente construido a propósito) no está 100% asegurado por la solución
s2: desde 2 puntos en ⍵, devuelve la circunferencia en el formato ((XY) r) que tiene diámetro en esos 2 puntos
s3: desde 3 puntos devuelve la circunferencia en el formato ((XY) r) que pasa por esos tres puntos Si hay problemas (por ejemplo, los puntos están alineados), fallaría y devolvería ⍬.
tenga en cuenta que -. × encuentre el determinante de una matriz nxn y
s: a partir de n puntos en ⍵, encuentra las circunferencias de tipo de las encontradas por s2 o las de tipo s3 que contienen todos los n puntos.
s1: del conjunto encontrado en el s anterior calcula aquellos que tienen radio mínimo y devuelve el primero que tiene radio mínimo. Los tres números como matrices (la primera y la segunda coordenadas son las coordenadas del centro, mientras que la tercera es el radio de la circunferencia encontrada).
fuente
Python 2 (PyPy) ,
244242 bytesPruébalo en línea!
Esto utiliza el algoritmo de fuerza bruta O (n ^ 4), iterando a través de cada par y triángulo de puntos, calculando el centro y manteniendo el centro que necesita el radio más pequeño para encerrar todos los puntos. Calcula el circuncentro de 3 puntos al encontrar la intersección de dos bisectrices perpendiculares (o, si dos puntos son iguales, usa el punto medio con el tercero).
fuente
P={x+y*1j for x,y in input()}
ahorra 2 bytes también.Pitón
212190 bytesEsta solución es incorrecta y tengo que trabajar ahora, así que no tengo tiempo para solucionarlo.
Pruébalo en línea!
¡Descubrí qué dos puntos están más lejos y luego generé una ecuación para un círculo basada en esos puntos!
Sé que esto no es lo más corto en python, ¡pero es lo mejor que puedo hacer! Además, este es mi primer intento de hacer uno de estos, ¡así que comprendan!
fuente
if g>c:\n c=g\n d=[e,f]
aif g>c:c=g;d=[e,f]
, ahorrándole mucho espacio en blanco. No creo que necesite inicializar d de antemano, también usando dos variables yE,F=e,f
en la línea 10 lo haráprint
mucho más corto. Creo que una soluciónmax
y una comprensión de la lista sería incluso más corta que dos bucles, pero podría estar equivocado. Lamentablemente, sin embargo, su solución no es correcta. Para los puntos (-1,0), (0,1.41), (0.5, 0), (1,0) su solución calcula un círculo alrededor de 0 con radio 1. Pero el punto (1, 1.41) no está en ese circulo.