Dies ist eine Herausforderung, die von Chebyshev Rotation inspiriert wurde . Ich schlage vor, dort nach Antworten zu suchen, um Inspiration für diese Herausforderung zu erhalten.
Bei einem Punkt auf der Ebene gibt es ein eindeutiges Quadrat (ein Rechteck mit gleichen Seiten), das auf dem Ursprung zentriert ist und diesen Punkt schneidet ( interaktive Demo ):
Geben Sie für einen Punkt p und einen Abstand d den Punkt zurück, den Sie erhalten, indem Sie den Abstand d von p entgegen dem Uhrzeigersinn (und für ein negatives d im Uhrzeigersinn ) entlang des Umfangs des Quadrats verschieben, das auf dem Ursprung zentriert ist, der p schneidet . Ihre Antwort muss auf mindestens 4 Dezimalstellen genau sein.
Testfälle:
(0, 0), 100 -> (0, 0)
(1, 1), 81.42 -> (-0.4200, 1.0000)
(42.234, 234.12), 2303.34 -> (-234.1200, 80.0940)
(-23, -39.234), -234.3 -> (39.2340, -21.8960)
Die folgenden Testfälle stammen von Martin Ender und sind alle mit d = 1 :
(0, 0) -> (0, 0)
(1, 0) -> (1, 1)
(1, 1) -> (0, 1)
(0, 1) -> (-1, 1)
(-1, 1) -> (-1, 0)
(-1, 0) -> (-1, -1)
(-1, -1) -> (0, -1)
(0, -1) -> (1, -1)
(1, -1) -> (1, 0)
(95, -12) -> (95, -11)
(127, 127) -> (126, 127)
(-2, 101) -> (-3, 101)
(-65, 65) -> (-65, 64)
(-127, 42) -> (-127, 41)
(-9, -9) -> (-8, -9)
(126, -127) -> (127, -127)
(105, -105) -> (105, -104)
Antworten:
Python 2,
363335296266262258256233 BytesWoo, 130 Bytes verloren! Vielen Dank an Neil für das Speichern von 4 Bytes, Nathan Merrill für das Speichern von 2 Bytes und xnor für das Speichern von lächerlichen 23 Bytes!
Die allgemeine Idee ist folgende: Wir können die zurückgelegte Strecke verringern, indem wir den Modul gegen den Umfang des Quadrats messen. Der Umfang ist definiert als das 8-fache der größten der beiden Koordinaten, da der Punkt darauf liegen muss. Dann, nachdem der Modul genommen wurde, ist garantiert, dass wir keine Überlappung haben. Dies garantiert auch, dass wir uns immer nur gegen den Uhrzeigersinn bewegen müssen, da der Modul ein positives Ergebnis liefert.
Von dort aus benutze ich einfach das, was wir aus den angegebenen x- und y-Koordinaten wissen, um herauszufinden, wo wir uns befinden: oben, unten, links, rechts oder in einer Ecke, und um die Richtung zu bestimmen, die eine der folgenden sein kann
0, 1, 2, 3
:Danach ist es so einfach wie ein Looping, während wir noch eine Distanz zurücklegen müssen. Basierend auf der Richtung, die wir subtrahieren oder zur entsprechenden Koordinate hinzufügen, teilen Sie der Schleife mit, in welche Richtung wir als Nächstes fahren.
Es ist zwar ziemlich lang, aber es funktioniert auf jeden Fall. Hier ist ein Beispiel für I / O:
Probieren Sie es online aus oder führen Sie Testfälle aus .
quelle
s=max(x,y,-x,-y)
Arbeit?(s>0)*(d>0)
ists>0<d
. Die Ausgabe kann sein"%.4f "*2%tuple(p)
.if s:d=d%(8*s)
kann seind%(s*8or 1)
.(r+1)
kann sein~-r
.1*(x>-s)
kann einfach sein(x>-s)
.abs(y)==abs(x)
kann seiny*y==x*x
(x>-s)
die ich vorgenommen habe, erforderten keine Klammern und~-r
Dekremente, also habe ich sie verwendet-~r
.JavaScript (ES6), 147 Byte
Erläuterung: Arbeitet so, dass versucht wird, den Richtungsvektor innerhalb der Grenzen des Quadrats zu addieren. Jegliches Überschießen wird rekursiv zurückgeführt, wobei die Richtung um 90 ° gegen den Uhrzeigersinn gedreht wird. Die Richtung wird tatsächlich unter Verwendung eines vertikalen Flags
v
und einer Einheit codiert,w
so dass die Vektoren (1, 0), (0, 1), (-1, 0) und (0, -1) mitv
0, 1, 0 codiert werden , 1 bzw.w
von 1, 1, -1, -1. Der Richtungsvektor zeigt möglicherweise anfangs nicht in eine geeignete Richtung, aber er zeigt niemals nach hinten, sodass er sich schließlich in eine verwendbare Richtung dreht.quelle
f(42.234, 234.12, 2303.34) -> [-234.12, 80.09399999999988]
was bedeutet, dass er keine 4-stellige Genauigkeit aufweist. Vielleicht könnte dies durch Hinzufügen einer Ausgabeformatierung behoben werden? Gute Antwort! :)