Trilaterieren Sie Ihre Position

11

Einführung

Stellen Sie sich vor, Sie befinden sich auf einer zweidimensionalen kartesischen Ebene und möchten Ihre Position darauf bestimmen. Sie kennen 3 Punkte in dieser Ebene und Ihre Entfernung zu jedem von ihnen. Während es immer möglich ist, Ihre Position daraus zu berechnen, ist es ziemlich schwierig, dies in Ihrem Kopf zu tun. Also beschließen Sie, ein Programm dafür zu schreiben.

Die Herausforderung

Geben Sie bei 3 Punkten und Ihrer Entfernung zu ihnen die Koordinaten Ihrer Position aus.

  • Die Eingabe und Ausgabe kann in jedem geeigneten Format erfolgen, einschließlich der Verwendung komplexer statt reeller Zahlen. Bitte klären Sie in Ihrer Antwort, welches Format Sie verwenden.
  • Sie erhalten immer genau 3 verschiedene Punkte mit ihrer Entfernung zu Ihnen.
  • Die Koordinaten und Abstände sind Gleitkommazahlen mit beliebiger Genauigkeit. Ihre Ausgabe muss auf 3 Dezimalstellen korrekt sein. Die Rundung liegt bei Ihnen. Bitte klären Sie in Ihrer Antwort.
  • Sie können davon ausgehen, dass die drei Punkte nicht kollinear sind, sodass es immer eine eindeutige Lösung gibt.
  • Sie dürfen die Lösung nicht brutal erzwingen.
  • Sie dürfen keine integrierten Funktionen verwenden, die dieses spezielle Problem trivialisieren. Builtins für Vektornormen usw. sind jedoch zulässig.

Tipp, um loszulegen:

Stellen Sie sich einen Kreis um jeden dieser 3 Punkte mit ihrem Abstand zu Ihnen als Radius vor.

Regeln

  • Funktion oder volles Programm erlaubt.
  • Standardregeln für die Eingabe / Ausgabe.
  • Es gelten Standardlücken .
  • Dies ist , also gewinnt die niedrigste Byte-Anzahl. Tiebreaker ist eine frühere Einreichung.

Testfälle

Das Eingabeformat für einen Punkt ist hier [[x,y],d]mit xund yals Koordinaten und dals Abstand zu diesem Punkt. Die 3 dieser Punkte sind in einer Liste angeordnet. Die Ausgabe erfolgt xund dann yin einer Liste.

[[[1, 2], 1.414], [[1, 1], 2.236], [[2, 2], 1.0]] -> [2, 3]
[[[24.234, -13,902], 31,46], [[12,3242, 234,12], 229,953], [[23,983, 0,321], 25,572]] -> [-1,234, 4,567]
[[[973.23, -123.221], 1398.016], [[-12.123, -98.001], 990.537], [[-176.92, 0], 912.087]] -> [12.345, 892.234]

Mit diesem Pyth-Programm können Sie zusätzliche Testfälle generieren . Die Position befindet sich in der ersten Zeile der Eingabe und die 3 Punkte befinden sich in den folgenden 3 Zeilen.

Viel Spaß beim Codieren!

Denker
quelle
Da der Code auf eine zweidimensionale kartesische Ebene passen muss, muss er so kurz wie möglich sein.
wizzwizz4
Sie verwenden offensichtlich ungenaue Ergebnisse, die immer noch zu Unklarheiten führen können. Wie sollen wir damit umgehen?
Fehler
@flawr Nehmen Sie einfach an, dass alle Ergebnisse genau und eindeutig sind. Ihr Programm sollte für Fälle mit sehr wenigen Dezimalstellen funktionieren. Machen Sie sich keine Sorgen über Mehrdeutigkeiten. Ich werde die Herausforderung aufräumen, wenn ich zu Hause bin.
Denker
Da die akzeptierte Antwort praktisch nur ein Grafikrechner ist, werde ich erwähnen, dass es in TI-Basic (68k-Version) eine 96-Byte-Lösung gibt. Um zu klären, wird solvetrivialisiert das Problem (drei Kreis Gleichungen gegeben)? Ich dachte es wäre, aber wenn du mit solchen Dingen einverstanden bist, werde ich es veröffentlichen.
Fox

Antworten:

4

Desmos, 122 Bytes

Online-Nutzung . Kopieren Sie jede Gleichung und fügen Sie sie in ein Gleichungsfeld ein. Klicken Sie für jedes Feld auf "Alle hinzufügen", klicken Sie dann auf den Schnittpunkt und geben Sie den entsprechenden Wert ein. jeweils A, Bund Cdie Abstände für die Punkte (a,b), (c,d), und (E,f)sind. Um eine Quadratwurzel im Wert zu erhalten, geben Sie sqrtden Wert in das Feld ein.

\left(x-a\right)^2+\left(y-b\right)^2=AA
\left(x-c\right)^2+\left(y-d\right)^2=BB
\left(x-E\right)^2+\left(y-f\right)^2=CC

Überprüfen Sie den ersten Testfall .

Oder schauen Sie hier:

Kreise!

Conor O'Brien
quelle
Das sieht ziemlich gut aus, aber erfüllt dies unsere Kriterien für Programmiersprachen? Das sieht für mich wie ein Plot-Tool aus, habe es aber nie benutzt, also könnte ich mich irren.
Denker
1
@DenkerAffe Ich habe tatsächlich eine Frage dazu auf Meta gestellt , und es zählt in der Tat.
Conor O'Brien
2
Okay, dann meine positive Stimme :)
Denker
Ich bestreite die Anzahl der Bytes. Sie können kostenlos auf den Schnittpunkt klicken, was nicht richtig erscheint.
Lirtosiast
@lirtosiast Ich würde argumentieren, dass der Punkt per Definition immer da ist und weiter sagen, dass das OP sagte, dass diese Art der Interaktion in Ordnung war. Wenn Sie jedoch der Meinung sind, dass es eine Strafe geben sollte, bin ich offen für Vorschläge.
Conor O'Brien
4

C 362 348 345 Bytes

Die Eingabe erfolgt als Folge von durch Leerzeichen getrennten Floats auf stdin : x1 y1 d1 x2 y2 d2 x3 y3 d3. Die Ausgabe ist auf stdout ähnlich : x y.

#define F"%f "
#define G float
#define T(x)(b.x*b.x-a.x*a.x)
typedef struct{G a;G b;G c;}C;G f(C a,C b,G*c){G x=b.b-a.b;*c=(T(a)+T(b)-T(c))/x/2;return(a.a-b.a)/x;}main(){C a,b,c;G x,y,z,t,m;scanf(F F F F F F F F F,&a.a,&a.b,&a.c,&b.a,&b.b,&b.c,&c.a,&c.b,&c.c);x=f(a,a.b==b.b?c:b,&y);z=f(b.b==c.b?a:b,c,&t);m=t-y;m/=x-z;printf(F F"\n",m,x*m+y);}

Cist ein Strukturtyp, dessen Elemente eine x-Koordinate a, eine y-Koordinate bund ein Abstand (Radius) sind c. Die Funktion verwendet fzwei CStrukturen und einen Zeiger auf einen Float und bestimmt die Linie, an der sich die C(Kreise) schneiden. Der y-Achsenabschnitt dieser Linie wird in den Schwimmer gelegt, und die Steigung wird zurückgegeben.

Das Programm ruft fzwei Kreispaare auf und bestimmt dann den Schnittpunkt der erzeugten Linien.

Fuchs
quelle
Da wir klargestellt haben, dass die Eingaben nicht kollinear sind, werden die erzeugten Linien fniemals parallel sein. Die Tests sollen sicherstellen, dass sie auch nicht vertikal sind, da ich die Steigungsschnittform verwende. Auf diese Weise gibt es immer genau eine Antwort.
Fox
2

Python - 172

Nimmt die Eingabe als Liste von Formulartupeln (x, y, d) auf. Lassen Sie mich wissen, wenn Sie einen Weg sehen, wie Sie weiter Golf spielen können. Ich denke, es muss einen geben, aber ich kann es nicht herausfinden!

import numpy as N
def L(P):
    Z=[p[2]**2-p[0]**2-p[1]**2 for p in P];return N.linalg.solve([[P[i][0]-P[0][0],P[i][1]-P[0][1]]for i in[1,2]],[(Z[0]-Z[i])*0.5 for i in [1,2]])
RT
quelle
Sie können hier einige Leerzeichen weglassen. So etwas -1 if 1 else 1kann zum -1if 1else 1Beispiel werden. Dies funktioniert auch mit Klammern. Es gibt einige Stellen, an denen Sie dies nutzen können. Ist auch .5das gleiche wie 0.5.
Denker