Die Manhattan-Entfernung in einem regelmäßigen Raster ist die Anzahl der orthogonalen Schritte, die erforderlich sind, um eine Zelle von einer anderen zu erreichen. Orthogonale Schritte sind diejenigen, die durch die Kanten der Gitterzellen verlaufen (im Gegensatz zu den Ecken, die uns den Chebyshev-Abstand geben würden ).
Wir können einen ähnlichen Abstand für andere Gitter definieren, zum Beispiel für das Dreiecksgitter. Wir können die einzelnen Zellen im Raster mit dem folgenden Indizierungsschema ansprechen, wobei jede Zelle ein x,y
Paar enthält :
____________________________________...
/\ /\ /\ /\ /\
/ \ 1,0/ \ 3,0/ \ 5,0/ \ 7,0/ \
/ 0,0\ / 2,0\ / 4,0\ / 6,0\ / 8,0\
/______\/______\/______\/______\/______\...
\ /\ /\ /\ /\ /
\ 0,1/ \ 2,1/ \ 4,1/ \ 6,1/ \ 8,1/
\ / 1,1\ / 3,1\ / 5,1\ / 7,1\ /
\/______\/______\/______\/______\/___...
/\ /\ /\ /\ /\
/ \ 1,2/ \ 3,2/ \ 5,2/ \ 7,2/ \
/ 0,2\ / 2,2\ / 4,2\ / 6,2\ / 8,2\
/______\/______\/______\/______\/______\...
\ /\ /\ /\ /\ /
\ 0,3/ \ 2,3/ \ 4,3/ \ 6,3/ \ 8,3/
\ / 1,3\ / 3,3\ / 5,3\ / 7,3\ /
\/______\/______\/______\/______\/___...
/\ /\ /\ /\ /\
. . . . . . . . . .
. . . . . . . . . .
Nun ist die Manhattan-Distanz in diesem Raster wieder die minimale Anzahl von Schritten über Kanten, um von einer Zelle zur anderen zu gelangen. So können Sie aus bewegen 3,1
zu 2,1
, 4,1
oder 3,2
, aber nicht auf anderes Dreieck, da diese Punkte überqueren würde , statt Kanten.
Zum Beispiel ist die Entfernung von 2,1
zu 5,2
ist 4
. Der kürzeste Weg ist im Allgemeinen nicht eindeutig, aber eine Möglichkeit, die Entfernung in 4 Schritten zu ermitteln, ist:
2,1 --> 3,1 --> 3,2 --> 4,2 --> 5,2
Die Herausforderung
Geben Sie bei zwei Koordinatenpaaren und nach dem obigen Adressierungsschema den Manhattan-Abstand zwischen ihnen zurück.x1,y1
x2,y2
Sie können davon ausgehen, dass alle vier Eingaben nicht negative Ganzzahlen mit jeweils weniger als 128 sind. Sie können diese in beliebiger Reihenfolge und willkürlich gruppieren (vier separate Argumente, eine Liste mit vier Ganzzahlen, zwei Paare von Ganzzahlen, eine 2x2-Matrix, ...). .).
Sie können ein Programm oder eine Funktion schreiben und eine der Standardmethoden zum Empfangen von Eingaben und zum Bereitstellen von Ausgaben 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
Jeder Testfall wird als gegeben .x1,y1 x2,y2 => result
1,2 1,2 => 0
0,1 1,1 => 1
1,0 1,1 => 3
2,1 5,2 => 4
0,0 0,127 => 253
0,0 127,0 => 127
0,0 127,127 => 254
0,127 127,0 => 254
0,127 127,127 => 127
127,0 127,127 => 255
75,7 69,2 => 11
47,58 36,79 => 42
77,9 111,23 => 48
123,100 111,60 => 80
120,23 55,41 => 83
28,20 91,68 => 111
85,107 69,46 => 123
16,25 100,100 => 159
62,85 22,5 => 160
92,26 59,113 => 174
62,22 35,125 => 206
quelle
(a,b,x,y)->c(a,b,x,y,0)
(getrennte Methodec
mit den vier Argumenten und0
als fünftes Argument aufrufen ).Antworten:
JavaScript (ES6),
84 bis78 Byte6 Bytes gespart dank Neil
Testfälle
Code-Snippet anzeigen
Anfängliche rekursive Lösung,
1008881Dank ETHproductions 12 Bytes gespart Dank Neil 7 Bytes gespart
Wie es funktioniert
Obwohl dies im Wesentlichen immer noch für die aktuelle Version gilt, bezieht sich die folgende Erläuterung genauer auf die ursprüngliche Version:
Es ist trivial, von (x0, y) nach (x1, y) zu gehen, da wir die Seitenkanten vom Quellendreieck bis zum Zieldreieck überqueren können. Die Manhattan-Entfernung beträgt in diesem Fall | x0 - x1 | .
Der schwierige Teil sind die vertikalen Stufen. Um von Zeile y0 zu Zeile y1 zu gelangen , müssen diese beiden Parameter berücksichtigt werden:
Die Ausrichtung eines Dreiecks ergibt sich aus der Parität von x + y :
Wir können von einem nach oben weisenden Dreieck (nützlich, wenn y0 <y1 ) nach unten und von einem nach unten weisenden Dreieck (nützlich, wenn y0> y1 ) nach oben gehen.
Durch Kombinieren der Ausrichtung des Dreiecks mit dem Vergleich zwischen y0 und y1 erhalten wir die Formel x + y0 + (y0> y1? 1: 0), deren Ergebnis gerade ist, wenn wir in die gewünschte Richtung gehen können, und ungerade, wenn nicht.
Wenn wir die nächste Zeile nicht direkt erreichen können, müssen wir zuerst eine korrekte Ausrichtung erhalten, indem wir x aktualisieren :
Testfälle
Code-Snippet anzeigen
quelle
n
Variable nicht komplett überspringen und nur 1 zum Ergebnis jeder Iteration hinzufügen? ( 90 Zeichen, denke ich)&
bedeutet, dass Siea+b+(b>d)&1
2 Bytes einsparen könnenf=(a,b,c,d,e=b==d|a+b+(b>d)&1)=>a-c|b-d&&f(e?a+1-2*(a>c):a,e?b:b+1-2*(b>d),c,d)+1
Python 2, 74 Bytes
quelle
**(x^y^(Y>=y))
?Batch, 99 Bytes
Erläuterung: Bei einer Bewegung nur für den Horizont wird einfach die absolute Differenz der x-Koordinaten berechnet. Bei ausreichend großen x-Werten benötigt die vertikale Bewegung nur einen zusätzlichen Schritt pro absoluter y-Koordinatendifferenz, bei kleinen x-Werten jedoch vier zusätzliche Schritte pro zwei y-Koordinatendifferenzen sowie einen oder drei Schritte für eine ungerade Differenz. Dies wird in zwei Schritten pro Differenz plus einem Korrekturfaktor berechnet. Das Ergebnis ist dann der größere der beiden korrigierten Schritte und die Summe der absoluten Differenzen, obwohl dies selbst als der größere der korrigierten absoluten y-Koordinatendifferenz und des absoluten x-Koordinatendistanz berechnet wird, die zu der nicht korrigierten absoluten y-Koordinatendifferenz addiert werden .
@cmd/cset/a"
- Wertet kommagetrennte Ausdrücke aus und druckt den letztenx=%3-%1,x*=x>>31|1
y=%4-%2,w=y>>31,y*=w|1
z=x+(y+x&1)*(-(%1+%2+w&1)|1)-y
z*=z>>31,x+y+z
quelle
Gelee , 24 Bytes
Probieren Sie es online!
quelle
Schläger / Schema, 214 Bytes
quelle
05AB1E , 24 Byte
Probieren Sie es online!
Nervenzusammenbruch
quelle
©
zuD
und entfernen Sie das®
? Es scheint für den Fall in Ihrem TIO zu funktionieren, aber ich bin nicht sicher, ob es in jedem Fall den gleichen Weg geht.M
das Verhalten hiervon betroffen wäre. Scheitert für[[0, 127], [0, 0]]
.Python 2 ,
747271 BytesProbieren Sie es online! Link enthält Testfälle. Bearbeiten: 2 Bytes dank @JoKing gespeichert. Dank @ Mr.Xcoder wurde ein weiteres Byte gespeichert. Basierend auf der folgenden Formel habe ich in dieser Frage gefunden :
quelle
lambda c,a,d,b:abs(a-b)+abs(a+-(c+a)/2-b--(d+b)/2)+abs((c+a)/2-(d+b)/2)
sollte 3 Bytes sparen.Pyth ,
3128 BytesProbieren Sie es hier aus! oder Testen Sie die Testsuite!
Nervenzusammenbruch
quelle
05AB1E , 16 Bytes
Probieren Sie es online! oder Testen Sie die Testsuite! (Verwendet eine leicht modifizierte Version des Codes (
®
anstelle von²
), mit freundlicher Genehmigung von Kevin Cruijssen )quelle
©+®
, istDŠ+
es einfacher, eine Testsuite einzurichten. ;) Hier ist diese Testsuite, und alle Testfälle sind in der Tat erfolgreich (ignorieren Sie den unordentlichen Header; p).Jelly ,
22 .. 1615 BytesProbieren Sie es online!
Probieren Sie alle Testfälle aus.
Verwendet in dieser Antwort die @ Neil-Methode , die eine modifizierte Formel aus dieser math.SE-Frage verwendet.
Nimmt die Koordinaten als Argumente
y1, y2
undx1, x2
.quelle
Java 8,
157190188144142141127 Bytes+33 Bytes (157 → 190) aufgrund einer Fehlerbehebung.
-44 Bytes (188 → 144) Konvertieren der rekursiven Methode in eine Einzelschleifenmethode.
-14 Bytes dank @ceilingcat .
Erläuterung:
Probieren Sie es hier aus.
quelle
z*z<c*c
stattdessen vor(z<0?-z:z)<(c<0?-c:c)