Entourez trois points

13

Étant donné les coordonnées cartésiennes de trois points sur un plan, trouvez l'équation du cercle à travers tous. Les trois points ne seront pas en ligne droite.

Chaque ligne d'entrée de votre programme contiendra les coordonnées xet yde trois points, dans l'ordre A(x),A(y),B(x),B(y),C(x),C(y). Ces coordonnées seront des nombres réels inférieurs à 1 000 000 séparés les uns des autres par l'espace.

La solution doit être imprimée comme une équation du formulaire (x-h)^2 + (y-k)^2 = r^2. Les valeurs de h, k, rdoivent être imprimés avec trois chiffres après la virgule. Les signes plus et moins dans les équations doivent être modifiés au besoin pour éviter plusieurs signes avant un nombre.

Sample Inputs

7.0 -5.0 -1.0 1.0 0.0 -6.0
1.0 7.0 8.0 6.0 7.0 -2.0

Sample Outputs

(x - 3.000)^2 + (y + 2.000)^2 = 5.000^2
(x - 3.921)^2 + (y - 2.447)^2 = 5.409^2
fR0DDY
la source
Peut-on utiliser des équations polaires ou paramétriques à la place?
Peter Olson
@peter No. De cette façon, il sera difficile de comparer avec d'autres réponses.
fR0DDY
Que doit-on produire en cas d'absence de solution unique? Quelles sont les contraintes sur la robustesse numérique?
Peter Taylor
@ peter-taylor Il est indiqué dans l'énoncé du problème que «les trois points ne seront pas sur une ligne droite».
fR0DDY
2
Certes, ce ne sont que quelques caractères, ce n'est donc pas une diatribe que ma solution pourrait être un peu plus courte, juste une question honnête ... mais si des espaces sont dans la spécification de sortie, cela ne devrait-il pas être obligatoire? Sinon, dans un code-golf, pourquoi quelqu'un respecterait-il les spécifications de sortie?
Rebecca Chernoff

Réponses:

6

Python, 176 189 caractères

import sys,re
for s in sys.stdin:x,y,z=eval(re.sub(r'(\S+) (\S+)',r'\1+\2j,',s));w=z-x;w/=y-x;c=(x-y)*(w-abs(w)**2)/2j/w.imag-x;print'(x%+.3f)^2+(y%+.3f)^2=%.3f^2'%(c.real,c.imag,abs(c+x))

Fait tout son travail dans le plan complexe. Je fais le calcul en bas de cette page . -cest le centre du cercle.

Keith Randall
la source
@Joey: oui, mon mauvais. Fixé.
Keith Randall
2

C # - 490

using System;class C{static void Main(){Func<string,double>p=s=>double.Parse(s);Func<double,string>t=s=>(s<0?"+ ":"- ")+Math.Abs(s).ToString("F3");foreach(var l in System.IO.File.ReadAllLines("i")){var v=l.Split();double a=p(v[0]),b=p(v[1]),c=p(v[2]),d=p(v[3]),e=p(v[4]),f=p(v[5]),m=(d-b)/(c-a),n=(f-d)/(e-c),x=(m*n*(b-f)+n*(a+c)-m*(c+e))/(2*(n-m)),y=-(x-(a+c)/2)/m+(b+d)/2,r=Math.Sqrt((x-a)*(x-a)+(y-b)*(y-b));Console.WriteLine("(x "+t(x)+")^2+(y "+t(y)+")^2 = "+r.ToString("F3")+"^2");}}}

Ceci trouve les 2 lignes entre AB et BC. Ensuite, il trouve où les bissectes de ces 2 lignes se croisent. (Ce que je viens de remarquer est ce que @PeterTaylor a mentionné dans son commentaire à @PeterOfTheCorn.)

Rebecca Chernoff
la source
2

Ruby, 192 caractères

$<.map{|l|a,b,c,d,e,f=l.split.map &:to_f
n=(f-d)/(e-c)
puts"(x%+.3f)^2+(y%+.3f)^2=%.3f^2"%[x=-(n*(a+c)+(n*(b-f)-(c+e))*m=(d-b)/(c-a))/2/n-=m,y=-(x+(a+c)/2)/m-(b+d)/2,((a+x)**2+(b+y)**2)**0.5]}

Exemples d'utilisation:

$ echo "7.0 -5.0 -1.0 1.0 0.0 -6.0
1.0 7.0 8.0 6.0 7.0 -2.0" | ruby circle.rb
(x-3.000)^2+(y+2.000)^2=5.000^2
(x-3.921)^2+(y-2.447)^2=5.409^2
Ventero
la source
Inline les missions à x, yet rdans l'appel à %devrait aider, si possible.
Lowjacker
@ Joey: Désolé, apparemment manqué cela lors de la lecture de la question. Fixé maintenant.
Ventero
1

Wolfram Alpha (27)

Je dis, utilisez l'outil approprié pour le travail.

equation circle ([Input1],[Input2]),([Input3],[Input4]),([Input5],[Input6])

Exemple ici .

Peter Olson
la source
6
Aucune manipulation d'entrée? Pas de prise en charge de plusieurs lignes d'entrée? Je dirais que cela n'est pas admissible.
Joey
0

Javascript (299)

La seule façon dont je pouvais penser à résoudre ce problème était de résoudre algébriquement trois équations pour trois inconnues pour trouver h, k et r.

p=prompt().split(' ');a=p[0],b=p[1],c=p[2],d=p[3],e=p[4],f=p[5];h=((a*a+b*b)*(f-d)+(c*c+d*d)*(b-f)+(e*e+f*f)*(d-b))/(a*(f-d)+c*(b-f)+e*(d-b))/2;k=((a*a+b*b)*(e-c)+(c*c+d*d)*(a-e)+(e*e+f*f)*(c-a))/(b*(e-c)+d*(a-e)+f*(c-a))/2;r=Math.sqrt((a-h)*(a-h)+(b-k)*(b-k));alert("(x-"+h+")²+(y-"+k+")²="+r+"²");

Exemple d'E / S:

7.0 -5.0 -1.0 1.0 0.0 -6.0 -> (x-3)²+(y--2)²=5²

1.0 7.0 8.0 6.0 7.0 -2.0 -> (x-3.9210526315789473)²+(y-2.4473684210526314)² =5.409159155551175²

Le seul bug que je vois est que si h ou k est négatif, il sort à la --place de +.

Peter Olson
la source
2
Cela peut être fait avec une boussole et un bord droit. Prenez deux points, tracez la ligne qui les divise. Prenez une paire différente de deux points, idem. Trouvez l'intersection. Que cela conduise à un code plus court, je n'ai pas encore étudié.
Peter Taylor
Cela ne gère qu'une seule ligne d'entrée, non?
Joey
@ Joey, oui. Le problème nécessite-t-il une gestion de plusieurs lignes?
Peter Olson
1
Citant la tâche: »Chaque ligne d'entrée de votre programme contiendra les coordonnées x et y de trois points ...«
Joey