La distance de Manhattan sur une grille régulière est le nombre de pas orthogonaux qu'il faut prendre pour atteindre une cellule à partir d'une autre. Les étapes orthogonales sont celles qui traversent les bords des cellules de la grille (par opposition aux coins, ce qui nous donnerait la distance de Chebyshev ).
On peut définir une distance similaire sur d'autres grilles, par exemple la grille triangulaire. Nous pouvons traiter les cellules individuelles de la grille avec le schéma d'indexation suivant, où chaque cellule contient une x,y
paire:
____________________________________...
/\ /\ /\ /\ /\
/ \ 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\ /
\/______\/______\/______\/______\/___...
/\ /\ /\ /\ /\
. . . . . . . . . .
. . . . . . . . . .
Maintenant, la distance de Manhattan sur cette grille est à nouveau le nombre minimal d'étapes à travers les bords pour passer d'une cellule à l'autre. Vous pouvez donc passer de 3,1
à 2,1
, 4,1
ou 3,2
, mais pas à n'importe quel autre triangle, car ce sont des points de croisement plutôt que des bords.
Par exemple, la distance de 2,1
à 5,2
est 4
. Le chemin le plus court n'est généralement pas unique, mais une façon de faire la distance en 4 étapes est:
2,1 --> 3,1 --> 3,2 --> 4,2 --> 5,2
Le défi
Étant donné deux paires de coordonnées et à partir du schéma d'adressage ci-dessus, renvoyez la distance Manhattan entre elles.x1,y1
x2,y2
Vous pouvez supposer que les quatre entrées sont des entiers non négatifs, chacun inférieur à 128. Vous pouvez les prendre dans n'importe quel ordre et regroupés arbitrairement (quatre arguments distincts, une liste de quatre entiers, deux paires d'entiers, une matrice 2x2, .. .).
Vous pouvez écrire un programme ou une fonction et utiliser l'une des méthodes standard de réception d'entrée et de sortie.
Vous pouvez utiliser n'importe quel langage de programmation , mais notez que ces failles sont interdites par défaut.
Il s'agit de code-golf , donc la réponse valide la plus courte - mesurée en octets - l'emporte.
Cas de test
Chaque cas de test est donné sous la forme .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
la source
(a,b,x,y)->c(a,b,x,y,0)
(appel de la méthode séparéec
avec les quatre arguments et0
comme cinquième argument) à ma réponse.Réponses:
JavaScript (ES6),
8478 octets6 octets enregistrés grâce à Neil
Cas de test
Afficher l'extrait de code
Solution récursive initiale,
100888112 octets enregistrés grâce à ETHproductions
7 octets enregistrés grâce à Neil
Comment ça marche
Bien qu'elle s'applique toujours essentiellement à la version actuelle, l'explication suivante se réfère plus spécifiquement à la version initiale:
Passer de (x0, y) à (x1, y) est trivial car nous pouvons traverser les bords latéraux tout le long du triangle source jusqu'au triangle cible. La distance de Manhattan dans ce cas est | x0 - x1 | .
La partie délicate est les étapes verticales. Pour passer de la ligne y0 à la ligne y1 , nous devons prendre en compte ces deux paramètres:
L'orientation d'un triangle est donnée par la parité de x + y :
On peut descendre d'un triangle pointant vers le haut (utile quand y0 <y1 ) et monter d'un triangle pointant vers le bas (utile quand y0> y1 ).
En combinant l'orientation du triangle avec la comparaison entre y0 et y1 , nous obtenons la formule x + y0 + (y0> y1? 1: 0) dont le résultat est même si nous pouvons aller dans la direction souhaitée et impair sinon.
Si nous ne pouvons pas atteindre directement la ligne suivante, nous devons d'abord obtenir un alignement correct en mettant à jour x :
Cas de test
Afficher l'extrait de code
la source
n
variable et ajouter simplement 1 au résultat de chaque itération? ( 90 caractères je pense)&
signifie que vous pouvez fairea+b+(b>d)&1
pour économiser 2 octetsf=(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 octets
la source
**(x^y^(Y>=y))
:?Lot, 99 octets
Explication: Un mouvement uniquement horizontal ne prend que la différence absolue de coordonnées x. Pour un assez grand x, le mouvement vertical ne prend qu'un pas supplémentaire par différence absolue de coordonnées y, mais pour un petit x, il faut quatre pas supplémentaires pour deux différences de coordonnées y, plus un ou trois pas pour une différence impaire. Ceci est calculé en deux étapes par différence plus un facteur de correction. Le plus grand des deux pas corrigés et la somme des différences absolues est alors le résultat, bien que cela soit lui-même calculé comme le plus grand de la différence de coordonnée y absolue corrigée et de la distance de coordonnée x absolue ajoutée à la différence de coordonnée y absolue non corrigée .
@cmd/cset/a"
- Évalue les expressions séparées par des virgules et imprime la dernièrex=%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
la source
Gelée , 24 octets
Essayez-le en ligne!
la source
raquette / schéma, 214 octets
la source
05AB1E , 24 octets
Port de ma réponse Pyth , qui à son tour utilise à peu près la même approche que la réponse Python de feersum . Prend l'entrée comme une liste de paires de coordonnées,( x1, x2) , ( y1, y2) . Correction d'un bug pour +1 octet, puis correction d'une autre erreur pour +1, mais qui donnait le résultat correct pour tous les cas de test ...
Essayez-le en ligne!
Panne
la source
©
pourD
et supprimer la®
? Cela semble fonctionner pour le cas actuellement dans votre TIO, mais je ne sais pas s'il suit le même chemin pour chaque cas.M
le comportement de cela en serait affecté. Échoue pour[[0, 127], [0, 0]]
.Python 2 ,
747271 octetsTry it online! Link includes test cases. Edit: Saved 2 bytes thanks to @JoKing. Saved a further byte thanks to @Mr.Xcoder. Based on the following formula I found in this question:
The coordinate systems differ in three ways; the coordinates are exchanged (which explains my somewhat strange parameter name order), the coordinates are angled at120∘ rather than 90∘ (which explains the two additions) and the coordinates in the linked question use inferior 1-indexing. Since we're taking differences this cancels out most of the time and we are left with:
This can then be golfed by noting that−⌊aj+12⌋=⌊−aj2⌋ .
la source
lambda c,a,d,b:abs(a-b)+abs(a+-(c+a)/2-b--(d+b)/2)+abs((c+a)/2-(d+b)/2)
should save 3 bytes.Pyth,
3128 bytesUses roughly the same approach as in feersum's Python answer. Takes input as a list of pairs of coordinates,(x1,x2),(y1,y2) . Fixed a bug for -1 byte.
Try it here! or Try the test suite!
Breakdown
la source
05AB1E, 16 bytes
Uses a modified version of Neil's answer, optimised for stack-based languages like 05AB1E. Takes input as two pairs of coordinates,(x1,x2),(y1,y2) , separated by a newline from STDIN. Initially I merged that with my other 05AB1E answer but then decided to post it separately because it's very, very different.
Try it online! or Try the test suite! (Uses a slightly modified version of the code (
®
instead of²
), courtesy of Kevin Cruijssen)la source
©+®
toDŠ+
it's easier to set up a test suite. ;) Here is that test suite, and all test cases are indeed succeeding (ignore the messy header ;p).Jelly,
22 .. 1615 bytesTry it online!
Try all test cases.
Uses @Neil's method in this answer which uses a modified formula from this math.SE question.
Takes the coordinates as arguments
y1, y2
andx1, x2
.la source
Java 8,
157190188144142141127 bytes+33 bytes (157 → 190) due to a bug fix.
-44 bytes (188 → 144) converting the recursive method to a single looping method.
-14 bytes thanks to @ceilingcat.
Explanation:
Try it here.
la source
z*z<c*c
instead of(z<0?-z:z)<(c<0?-c:c)