Le problème:
Étant donné un ensemble de points non vide dans le plan cartésien, trouvez le plus petit cercle qui les entoure tous ( lien Wikipedia ).
Ce problème est trivial si le nombre de points est de trois ou moins (s'il y a un point, le cercle a un rayon de zéro; s'il y a deux points, le segment de ligne qui rejoint les points est le diamètre du cercle; s'il y a trois points (non colinéaires), il est possible d'obtenir l'équation d'un cercle qui les touche tous s'ils forment un triangle non obtus, ou un cercle qui ne touche que deux points et entoure le troisième si le triangle est obtus). Donc, pour relever ce défi, le nombre de points devrait être supérieur à trois.
Le défi:
- Entrée: une liste de 4 points non colinéaires ou plus. Les points doivent avoir des coordonnées X et Y; les coordonnées peuvent être des flottants. Pour faciliter le défi, deux points ne doivent pas partager la même coordonnée X.
Par exemple:[(0,0), (2,1), (5,3), (-1,-1)]
- Sortie: Un tuple de valeurs
(h,k,r)
tel que est l'équation du plus petit cercle qui entoure tous les points.
Règles:
- Vous pouvez choisir la méthode de saisie qui convient à votre programme.
- La sortie doit être imprimée
STDOUT
ou retournée par une fonction. - Les langues «normales», à usage général, sont préférées, mais tout esolang est acceptable.
- Vous pouvez supposer que les points ne sont pas colinéaires.
- Il s'agit de code-golf, donc le plus petit programme en octets gagne. Le gagnant sera sélectionné une semaine après la publication du défi.
- Veuillez inclure la langue que vous avez utilisée et la longueur en octets comme en-tête dans la première ligne de votre réponse:
# Language: n bytes
- Veuillez inclure la langue que vous avez utilisée et la longueur en octets comme en-tête dans la première ligne de votre réponse:
Cas de test:
- 1:
- Contribution:
[(-8,0), (3,1), (-6.2,-8), (3,9.5)]
- Sortie:
[-1.6, 0.75, 9.89]
- Contribution:
- 2:
- Contribution:
[(7.1,-6.9), (-7,-9), (5,10), (-9.5,-8)]
- Sortie:
[-1.73, 0.58, 11.58]
- Contribution:
- 3:
- Contribution:
[(0,0), (1,2), (3,-4), (4,-5), (10,-10)]
- Sortie:
[5.5, -4, 7.5]
- Contribution:
- 4:
- Contribution:
[(6,6), (-6,7), (-7,-6), (6,-8)]
- Sortie:
[0, -0.5, 9.60]
- Contribution:
Bon golf !!!
Réponses:
Wolfram Language (Mathematica) ,
2827 octetsEssayez-le en ligne!
Les fonctions intégrées sont pratiques ici. La sortie est un objet disque avec le centre et le rayon. Comme d'autres, j'ai trouvé que les 2e et 3e cas de test étaient différents de la question.
Merci à @lirtosiast d'avoir enregistré un octet!
Si une liste est requise en sortie, cela peut être fait en 35 octets (au prix de 8 octets supplémentaires) . Merci à @Roman de l'avoir signalé.
la source
Append@@BoundingRegion[#,"MinDisk"]&
JavaScript (ES6),
298 ... 243242 octetsRenvoie un tableau
[x, y, r]
.Essayez-le en ligne!
ou voir une version formatée
Comment?
Méthode
Pour chaque paire de points(A,B) , on génère le cercle (X,Y,r) dont le diamètre est AB .
Pour chaque triple de points distincts(A,B,C) , on génère le cercle (X,Y,r) qui circonscrit du triangle ABC .
Et nous retournons finalement le plus petit cercle valide.
la mise en oeuvre
This way, the helper functionF requires only two parameters (j,k) to compute each coordinate:
The third parameter used inF (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.
la source
R, 59 bytes
Try it online!
Takes input as a vector of complex coordinates.
Mod
is the distance (modulus) in the complex plane andnlm
is an optimization function: it finds the position of the center (output asestimate
) which minimizes the maximum distance to the input points, and gives the corresponding distance (output asminimum
), 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: they%*%c(1,1i)
business converts it to a complex.la source
Gelée ,
10098 octetsEssayez-le en ligne!
Contrairement à ma réponse en langue Wolfram , Jelly a besoin de beaucoup de code pour y parvenir (sauf si je manque quelque chose!). Ce programme complet prend la liste des points comme argument et renvoie le centre et le rayon du plus petit cercle englobant. Il génère des cercles pour tous les ensembles de trois points et des diamètres pour tous les ensembles de deux points, vérifie tous les points, puis sélectionne celui ayant le plus petit rayon.
Le code du bit make_circumcircle a été inspiré par le code de ce site , à son tour inspiré par Wikipedia.
la source
APL (NARS), 348 caractères, 696 octets
Il s'agit d'une 'implémentation' de formules dans la solution Arnauld ... Résultats et commentaires:
f: trouve la combinaison d'alpha ojets dans l'ensemble oméga
((X, Y), r) représentent désormais une circonférence de rayon r et de centre dans (XY).
c: trouve si le point dans ⍺ est à l'intérieur de la circonférence ((XY) r) dans ⍵ (résultat <= 0) ot il est externe (résultat> 0) Dans le cas de la circonférence entrée dans ⍵ c'est ⍬ comme entrée, il renverrait 1 (hors circonférence) chaque entrée possible dans ⍺.
p: si ⍵ est un tableau de ((XY) r); pour chacun des ((XY) r) dans ⍵ écrit 1 si tous les points du tableau ⍺ sont internes à ((XY) r) sinon écrit 0 NB Voici quelque chose qui ne va pas parce que je devais arrondir à epsilon = 1e¯ 13. en d'autres termes dans des cas limites de points dans l'avion (et probablement construits exprès) ce n'est pas une solution 100% assurée
s2: à partir de 2 points en ⍵, il renvoie la circonférence au format ((XY) r) qui a un diamètre dans ces 2 points
s3: à partir de 3 points, il retourne la circonférence au format ((XY) r) passant par ces trois points S'il y a des problèmes (par exemple les points sont alignés), il échouera et retournera ⍬.
notons que -. × trouve le déterminant d'une matrice nxn et
s: à partir de n points dans ⍵, il trouve les circonférences de type de celles trouvées par s2 ou celles de type s3 qui contiennent tous les n points.
s1: à partir de l'ensemble trouvé à partir du s ci-dessus calcule ceux qui ont un rayon minimum et renvoie le premier qui a un rayon minimum. Les trois nombres sous forme de tableaux (les première et deuxième coordonnées sont les coordonnées du centre, tandis que le troisième est le rayon de la circonférence trouvée).
la source
Python 2 (PyPy),
244242 bytesTry it online!
This uses the brute-force O(n^4) algorithm, iterating through each pair and triangle of points, calculating the centre, and keeping the centre that needs the smallest radius to enclose all points. It calculates the circumcentre of 3 points via finding the intersection of two perpendicular bisectors (or, if two points are equal it uses the midpoint with the third).
la source
P={x+y*1j for x,y in input()}
saves 2 bytes as well.Python
212190 bytesThis solution is incorrect, and I have to work now so I do not have time to fix it.
Try it online!
I figured out which two points are furthest and then I generated an equation for a circle based off those points!
I know this isn't the shortest in python, but it's the best I could do! Also this is my first attempt at doing one of these, so please be understanding!
la source
if g>c:\n c=g\n d=[e,f]
toif g>c:c=g;d=[e,f]
, saving you a lot of whitespace. I don't think you need to initialise d beforehand, also using two variables andE,F=e,f
in line 10 will make yourprint
a lot shorter. I think a solution withmax
and a list comprehension would be even shorter than two loops, but I might be wrong. Sadly, however, your solution is not correct. For the points (-1,0), (0,1.41), (0.5, 0), (1,0) your solution computes a circle around 0 with radius 1. But the point (1, 1.41) is not in that circle.