Stellen Sie sich ein reguläres Gitter vor, in dem jede Zelle Ganzzahlkoordinaten hat. Wir können die Zellen in (quadratische) "Ringe" gruppieren, wobei die Zellen in jedem Ring den gleichen Chebyshev-Abstand (oder Schachbrettabstand) vom Ursprung haben. Ihre Aufgabe ist es, eine solche Zellenkoordinate zu nehmen und diese Zelle innerhalb ihres Rings um eine Position gegen den Uhrzeigersinn zu drehen. Dies implementiert die folgende Zuordnung:
Wenn der Eingang also zum Beispiel ist (3, -2)
, sollten Sie ihn ausgeben (3, -1)
. Beachten Sie, dass dies (0, 0)
die einzige Eingabe ist, die sich selbst zuordnen sollte.
Regeln
Das E / A-Format ist ziemlich flexibel. Sie können zwei einzelne Zahlen, ein Paar / eine Liste / ein Array / ein Tupel von Zahlen, eine einzelne komplexe Zahl, eine Zeichenfolge mit zwei Zahlen usw. verwenden.
Sie können das annehmen -128 < x,y < 128
.
Sie können ein Programm oder eine Funktion schreiben und eine unserer Standardmethoden zum Empfangen und Bereitstellen von Eingaben verwenden.
Sie können jede Programmiersprache verwenden , beachten Sie jedoch, dass diese Lücken standardmäßig verboten sind.
Das ist Code-Golf , also gewinnt die kürzeste gültige Antwort - gemessen in Bytes .
Testfälle
(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:
JavaScript (ES6),
60 bis59 ByteNimmt Eingaben mit aktueller Syntax entgegen
(x)(y)
und gibt ein Array zurück[new_x, new_y]
.Wie es funktioniert
Unsere Hauptaufgabe ist es, zu bestimmen, in welchem Quadranten wir uns befinden, damit wir wissen, in welche Richtung wir uns bewegen müssen.
Wir können diese Formel als erste Annäherung verwenden:
Folgendes bekommen wir:
Fast dort. Die unteren linken und rechten Ecken der Ringe sind jedoch ungültig. Wir müssen die untere Hälfte der Matrix um eine Position nach links verschieben, also definieren wir
z
als:Und wir ersetzen
x
mitz
in unserer Formel:Was dazu führt:
Die gesamte Matrix ist nun korrekt, mit Ausnahme des Sonderfalls
[0, 0]
(überhaupt keine Bewegung), der separat behandelt werden muss.Testfälle
Code-Snippet anzeigen
quelle
Jelly ,
201412 BytesEingabe und Ausgabe erfolgen in Form von Arrays. Probieren Sie es online! oder überprüfen Sie alle Testfälle .
Hintergrund
Um herauszufinden, in welche Richtung wir uns bewegen müssen, können wir die relative Position des Startpunkts zu den Quadrantenhalbierenden x + y = 0 (blau) und x - y = 0 (rot) beobachten.
Der Ursprung ist festgelegt. Wir rücken vor, indem wir [0, 0] zum Startpunkt addieren .
Punkte im obersten Dreieck - einschließlich der Winkelhalbierenden des ersten Quadranten - haben eine positive Summe und ein nicht negatives Delta ( y - x ). Wir rücken vor, indem wir [-1, 0] zum Startpunkt addieren .
Punkte im äußersten linken Dreieck - einschließlich der Winkelhalbierenden des zweiten Quadranten - haben eine nicht positive Summe und ein positives Delta. Wir rücken vor, indem wir [0, -1] zum Startpunkt addieren .
Punkte im untersten Dreieck - einschließlich der Winkelhalbierenden des dritten Quadranten - haben eine negative Summe und ein nicht positives Delta. Wir rücken vor, indem wir [1, 0] zum Startpunkt addieren .
Punkte im äußersten rechten Dreieck - einschließlich der Winkelhalbierenden des vierten Quadranten - haben eine nicht negative Summe und ein negatives Delta. Wir rücken vor, indem wir [0, 1] zum Startpunkt addieren .
Um die richtige Richtung herauszufinden, berechnen wir [-sign (x + y), -sign (y - x)] , was nur neun mögliche Ergebnisse hat.
Die folgende Tabelle zeigt, welche Ergebnisse welchen Richtungen zugeordnet werden müssen.
Dies lässt drei Fälle.
Wenn mindestens eines der Vorzeichen 0 ist , ist [Δx, Δy] = [-Zeichen (x + y), -Zeichen (yx)] .
Wenn die Vorzeichen gleich und ungleich Null sind, ist [Δx, Δy] = [-Zeichen (x + y), 0] .
Wenn sich die Vorzeichen unterscheiden und nicht Null sind, ist [Δx, Δy] = [0, -Zeichen (yx)] .
Wie es funktioniert
quelle
Pyth , 19 Bytes
Probieren Sie es online!
Übersetzung meiner Julia-Antwort :
quelle
Python, 55 Bytes
Erkennt die vier diagonalen Quadranten und verschiebt die entsprechende Koordinate.
quelle
Haskell,
777169 BytesDies überprüft nur jeden dieser geneigten Quadranten und modifiziert die Eingabe entsprechend. Beachten Sie, dass die Leerzeichen notwendig sind, da sie sonst zB
>-
als Operator verstanden werden (was nicht definiert ist).Vielen Dank an @nimi, dass Sie ein paar weitere Bytes entfernt haben!
quelle
,
statt&&
innerhalb der ersten Wache speichert ein Byte. Und dann können Sie den zweiten Vergleich auf-x<y
für ein anderes Byte umschalten .,
!Rubin, 68
Die Lambda-Funktion nimmt eine komplexe Zahl als Argument und gibt eine komplexe Zahl zurück.
Wir drehen den Punkt viermal um 90 Grad, indem wir mit multiplizieren
i
. Es durchläuft daher alle 4 Quadranten und wird unverändert zurückgegeben - mit Ausnahme der Tatsache, dass wir es ändern, wenn es sich in einem bestimmten von ihnen befindet. Die Tatsache, dass es immer im selben Quadranten geändert wird, vereinfacht die Änderung.Es ist am einfachsten zu folgen, wenn wir es ändern,
z
wenn es sich im rechten Quadranten befindet. in diesem Fall müssen wir die y-Koordinate um 1 erhöhen (dhi
zuz
. hinzufügen )Wir überprüfen dies
x.abs>=y.abs
durch Vergleichen der Quadrate vonx
undy
. Dies sagt uns, dass der Punkt im rechten oder linken Quadranten liegt, nicht oben oder unten. Um zu überprüfen , es in der Tat im rechten Quadranten prüfen wir weiterhin , dassx>y
( die streng größer , weil wir den Fall ausschließen möchten ,x=y
die an der „Spitze“ Quadranten gehört.) Wo dies der Fall ist fügen wiri
zuz
.Aus Golfgründen ist das Hinzufügen
i
nicht wünschenswert. Stattdessen ändern wir die Zahl, wenn sie sich im unteren Quadranten befindet . In diesem Fall müssen wir 1 zurx
Koordinate hinzufügen (1 zu hinzufügenz
). In diesem Fall testen wir,y*y>=x*x
ob sie sich im oberen oder unteren Quadranten befindet. Um weiterhin sicherzustellen, dass es sich im unteren Quadranten befindet, müssen wir dies überprüfeny<-x
(wobei der Fall der unteren rechten Ecke strikt ausgeschlossen isty=-x
).Ein Vorteil dieser Prüfung ist, dass es keinen Sonderfall für die Koordinate 0,0 gibt. Leider wurde festgestellt, dass das Verschieben des Punktes zu einem anderen Quadranten führen kann und dies bedeutet, dass eine zweite Bewegung unterdrückt werden muss, wenn dieser Quadrant erneut überprüft wird, was wahrscheinlich den Vorteil zunichte macht.
Beispiel 1
Beispiel 2
Im Testprogramm
Diagramm
Das folgende Bild zeigt (blau) den Bereich
x*x>=y*y
, in dem (gelb) der Bereichy<-x
und (grün) der Schnittpunkt von diesen ist, der Bereich, in dem die korrekte Transformation die Addition von 1 zu istz
.quelle
Python, 52 Bytes
Komplexe Ein- und Ausgabe. Um zu testen, ob der Punkt im unteren diagonalen Quadranten liegt, drehen Sie ihn zuerst gegen den Uhrzeigersinn, um diesen Quadranten in den Standardquadranten (x> 0, y> 0) zu verschieben, und prüfen Sie, ob das Ergebnis kein Minuszeichen in der Zeichenfolgendarstellung enthält. Das Subtrahieren von 1 kümmert sich zuerst um die Randbedingung.
Wenn es sich nicht in diesem Quadranten befindet, drehen Sie das gesamte Problem um 90 Grad. Die Eingabe Null wird speziell behandelt, um sich selbst auszugeben.
Andere Versuche mit komplexen Zahlen:
quelle
Mathematica, 34 Bytes
Dies definiert einen unären Operator,
±
der eine komplexe Zahl annimmt und zurückgibt, deren Komponentenx
und darstelleny
.Nachdem Lynn die komplexe Zahlenlösung enthüllt hat und Dennis meine Punktzahl übertroffen hat, fühle ich mich nicht so schlecht, wenn ich meine referenzierte Golf-Implementierung poste. :) (Es stellt sich heraus, dass es praktisch identisch mit Lynns Antwort ist.)
quelle
MATL ,
1917 BytesDies verwendet komplexe Zahlen als Eingabe und Ausgabe.
Probieren Sie es online! Oder überprüfen Sie alle Testfälle .
Erläuterung
Nehmen wir
-127+42j
als Beispiel die Eingabe .quelle
Ruby, 51 Bytes
Ursprungsform
Alternatives Formular gemäß Xnors Kommentar
Verwendet die gleiche Art von Ungleichungen wie meine andere Antwort, jedoch auf andere Weise.
Im Testprogramm
quelle
d
Auftrag? Es sieht so aus, als ob Sie es einfach vergleichen könnenx*x>y*y
.y*y
und ist?
daher genau gleich lang. Ich habe es aufgenommen, da ich denke, dass Ihr Weg in gewisser Weise ordentlicher ist. Ich denke, Ruby versucht, es alsy?
einen legalen Funktionsnamen zu übergeben.Julia,
3834 BytesDennis sparte vier Bytes. Vielen Dank!
Probieren Sie es online!
quelle
int(2angle(z)/pi+5)
für dieselbe Byteanzahl verwenden (negative Potenzen verursachen einen Fehler, aus welchem Grund auch immer).!z=z+(z!=0)im^...
in allen Versionen speichern .C ++, 94 Bytes
Ungolfed:
Verwendung:
Probieren Sie es online aus
quelle
(x>0?x:-(x))
kann(x>0?x:-x)
.R
131110 BytesEine Funktion, die die beiden Ganzzahlen
x,y
als Eingaben verwendet und die Ausgabe in stdout schreibt. Die Lösung folgt dem Kontrollflussschema von @Dennis, könnte aber wahrscheinlich Golf spielen.BEARBEITEN: Code basierend auf @ JDLs Vorschlägen aktualisiert und eine Menge Bytes gespeichert.
Ungolfed
quelle
as.logical(-1)
istTRUE
, soX==0|Y==0
kann es werden!X|!Y
, und die Bedingungif(X!=Y...)
kann es werdenif(X-Y)
. Auch wennX==Y
undX!=0
dannY!=0
ist überflüssig. Eigentlich sind alle!=0
Teile überflüssig;if(X!=0)
ist äquivalent zuif(X)
.c(x,y)
anstattcat(x,y)
.JavaScript (ES6), 57 Byte (55–63 †)
Akzeptiert ein [x, y] -Array, ändert es direkt und gibt es zurück.
Wie es funktioniert
Dies ist eine Einzelparameter-Pfeilfunktion mit einem
return
-freien, präzisen Text.Der Parameter wird sofort in
x
undy
Variablen zerlegt.Der Kommaoperator kombiniert mehrere Ausdrücke zu einem, wobei das Ergebnis des letzten verwendet wird.
i
wird zur Unterscheidung von Inkrement- und Dekrementfällen verwendet. Wennx
größer als isty
, befinden wir uns entweder im unteren oder im rechten Quadranten und müssen in einer Dimension vorrücken (i=1
durch Booleschen-Zahlen-Zwang). Ebenso, wenn wir uns im negativen Teil der dividierenden x = y- Diagonale befinden. In allen anderen Fällen - einschließlich des Ursprungs - ist kein Inkrement erforderlich (i=0
).Wir verwenden einen ähnlichen Ausdruck, um zu steuern, welcher Array-Index angepasst werden soll. Wenn wir inkrementieren und nicht im linken oder unteren Quadranten (oder wenn wir nicht inkrementieren und im linken oder unteren Quadranten ), wird das bitweise XOR erzeugt
1
und der y- Wert angepasst. Ebenso, wenn wir uns auf der dividierenden x = -y- Diagonale befinden (einschließlich des Ursprungs). In allen anderen Fällen ist der Index0
( x ).Wenn dies der Fall
i
ist1
, werden wir es zum angegebenen Wert hinzufügen. Wanni
ist0
, werden wir genau dann 1 vom Wert abziehen, wenn wir nicht am Ursprung sind. Letzteres wird erkannt, indem einx|y
Wert ungleich Null ausgegeben wird, der durch booleschen Zwang auf {0, 1} begrenzt wird, und die Negation voni
ermöglicht die Verwendung von bitweisem ODER anstelle von logischem (da-1
keine Null-Bits vorhanden sind, ist es vor Änderungen sicher).Das Array ist das letzte, daher wird es zurückgegeben.
Testen
Code-Snippet anzeigen
† Variationen
Wir können zwei weitere Bytes einsparen, indem wir einen aussagekräftigen Rückgabewert überspringen und nur die Eingabemutation verwenden:
... oder wir können die Eingabemutation überspringen und alle Variablen für eine reine Funktion auf Kosten von sechs Bytes lokalisieren:
quelle
JavaScript (ES6),
80 bis76 Bytequelle
Haskell, 53 Bytes
Nimmt zwei Zahlen und gibt ein Tupel aus. Wenn sich der Punkt im östlichen Bereich befindet
-x<=y<x
, erhöhen Sie die zweite Koordinate um 1. Andernfalls können Sie die Quadranten durchlaufen, indem Sie den Eingabepunkt um 90 Grad drehen, die entsprechende Funktion aufrufen und dann zurückdrehen.quelle
Schläger 191 Bytes
Ungolfed (direktes Übersetzen der Figurenanweisungen in den Code ohne Verwendung einer Zwischenformel):
Testen:
Ausgabe:
quelle
Eigentlich 16 Bytes
Dies nimmt eine komplexe Zahl als Eingabe und gibt eine andere komplexe Zahl aus. Golfvorschläge willkommen! Probieren Sie es online!
Ungolfing
quelle
Scala, 184 Bytes
Ungolfed:
Erläuterung:
quelle