Odległość Manhattan na regularnej siatce jest liczba prostopadłych kroki trzeba podjąć, aby osiągnąć jedną komórkę z innego. Kroki ortogonalne to te, które przechodzą przez krawędzie komórek siatki (w przeciwieństwie do rogów, co dałoby nam odległość Czebyszewa ).
Możemy zdefiniować podobną odległość na innych siatkach, na przykład siatce trójkątnej. Możemy adresować poszczególne komórki w siatce za pomocą następującego schematu indeksowania, w którym każda komórka zawiera x,y
parę:
____________________________________...
/\ /\ /\ /\ /\
/ \ 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\ /
\/______\/______\/______\/______\/___...
/\ /\ /\ /\ /\
. . . . . . . . . .
. . . . . . . . . .
Teraz odległość Manhattanu na tej siatce jest znowu minimalną liczbą kroków wzdłuż krawędzi, aby przejść z jednej komórki do drugiej. Więc można przejść od 3,1
do 2,1
, 4,1
albo 3,2
, ale nie do jakiegokolwiek innego trójkąta, ponieważ te byłyby przekraczaniu punktów niż krawędzie.
Na przykład odległość od 2,1
do 5,2
wynosi 4
. Najkrótsza ścieżka zazwyczaj nie jest unikalna, ale jednym ze sposobów na pokonanie dystansu w 4 krokach jest:
2,1 --> 3,1 --> 3,2 --> 4,2 --> 5,2
Wyzwanie
Biorąc pod uwagę dwie pary współrzędnych i z powyższego schematu adresowania, zwróć odległość między nimi na Manhattanie.x1,y1
x2,y2
Możesz założyć, że wszystkie cztery wejścia są liczbami całkowitymi nieujemnymi, każde mniejsze niż 128. Możesz je uporządkować w dowolnej kolejności i dowolnie pogrupować (cztery oddzielne argumenty, lista czterech liczb całkowitych, dwie pary liczb całkowitych, macierz 2x2, ... .).
Możesz napisać program lub funkcję i użyć dowolnej ze standardowych metod odbierania danych wejściowych i dostarczania danych wyjściowych.
Możesz używać dowolnego języka programowania , ale pamiętaj, że te luki są domyślnie zabronione.
To jest golf golfowy , więc wygrywa najkrótsza ważna odpowiedź - mierzona w bajtach .
Przypadki testowe
Każdy przypadek testowy jest podany jako .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
źródło
(a,b,x,y)->c(a,b,x,y,0)
(wywołując metodę rozdzielonąc
z czterema argumentami i0
jako piąty argument) do mojej odpowiedzi.Odpowiedzi:
JavaScript (ES6),
8478 bajtówZaoszczędzono 6 bajtów dzięki Neilowi
Przypadki testowe
Pokaż fragment kodu
Wstępne rozwiązanie rekurencyjne,
1008881Zaoszczędź 12 bajtów dzięki ETHproductions
Zaoszczędź 7 bajtów dzięki Neilowi
Jak to działa
Chociaż nadal zasadniczo dotyczy bieżącej wersji, następujące wyjaśnienie odnosi się bardziej do wersji początkowej:
Przejście od (x0, y) do (x1, y) jest trywialne, ponieważ możemy przejść przez krawędzie boczne od trójkąta źródłowego do docelowego. Odległość Manhattanu w tym przypadku wynosi | x0 - x1 | .
Trudną częścią są pionowe kroki. Aby przejść z rzędu y0 do rzędu y1 , musimy wziąć pod uwagę te dwa parametry:
Orientację trójkąta określa parzystość x + y :
Możemy iść w dół od trójkąta skierowanego w górę (przydatne, gdy y0 <y1 ) i w górę od trójkąta skierowanego w dół (przydatne, gdy y0> y1 ).
Łącząc orientację trójkąta z porównaniem y0 i y1 , otrzymujemy wzór x + y0 + (y0> y1? 1: 0), którego wynik jest nawet jeśli możemy iść w pożądanym kierunku i dziwny, jeśli nie.
Jeśli nie możemy bezpośrednio przejść do następnego wiersza, najpierw musimy uzyskać prawidłowe wyrównanie, aktualizując x :
Przypadki testowe
Pokaż fragment kodu
źródło
n
całkowicie pominąć zmiennej i po prostu dodać 1 do wyniku każdej iteracji? ( Myślę, że 90 znaków )&
środków, które możesz zrobić,a+b+(b>d)&1
aby zaoszczędzić 2 bajtyf=(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 bajty
źródło
**(x^y^(Y>=y))
:?Partia, 99 bajtów
Objaśnienie: Ruch tylko horyzontalny przyjmuje absolutną różnicę współrzędnych x. W przypadku wystarczająco dużego x ruch pionowy zajmuje tylko jeden dodatkowy krok na bezwzględną różnicę współrzędnych y, ale dla małego x wymaga czterech dodatkowych kroków na dwie różnice współrzędnych y, plus jeden lub trzy kroki dla różnicy nieparzystej. Oblicza się to jako dwa kroki na różnicę plus współczynnik korygujący. Wynik jest większy z skorygowanych dwóch kroków i sumy różnic bezwzględnych, chociaż sam jest obliczany jako większy z poprawionej bezwzględnej różnicy współrzędnych y i bezwzględnej odległości współrzędnych x dodanej do nieskorygowanej bezwzględnej różnicy współrzędnych y .
@cmd/cset/a"
- Ocenia wyrażenia oddzielone przecinkami i drukuje ostatniex=%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
Obliczaźródło
Galaretka , 24 bajty
Wypróbuj online!
Nazwijmy wejście . Pracowałem według formuły feersum:(x,y),(X,Y)
Pierwszy wiersz oblicza , wykładnik w formule.¢=(Y≮y)+x+y
Ostatnia linia pierwsze Oblicza , a następnie oblicza się maksymalnie i , gdzie jest funkcją na środkowej linii.L=[|x−X|,|y−Y|] sum(L) f(L) f
Linia środkowa, ponieważ , Oblicza , który bierze się do „do potęgi, a następnie dodaje .L=[a,b] −((a+b)mod2) ¢ 2b
źródło
rakieta / schemat, 214 bajtów
źródło
05AB1E , 24 bajty
Port mojej odpowiedzi w Pythonie , który z kolei stosuje z grubsza to samo podejście, co w przypadku odpowiedzi w języku Python . Pobiera dane wejściowe jako listę par współrzędnych, . Naprawiono błąd dla +1 bajtu, a następnie naprawiono kolejny błąd dla +1, ale który dał poprawny wynik dla wszystkich przypadków testowych ...(x1,x2),(y1,y2)
Wypróbuj online!
Awaria
źródło
©
, abyD
i usunąć®
? Wygląda na to, że działa w przypadku obecnie w TIO, ale nie jestem pewien, czy podąża tą samą ścieżką dla każdego przypadku.M
wpłynęłoby to na jego zachowanie. Nie działa na[[0, 127], [0, 0]]
.Python 2 ,
747271 bajtówWypróbuj online! Link zawiera przypadki testowe. Edycja: Zapisano 2 bajty dzięki @JoKing. Zaoszczędzono kolejny bajt dzięki @ Mr.Xcoder. Na podstawie następującego wzoru znalazłem w tym pytaniu :
Układy współrzędnych różnią się na trzy sposoby; współrzędne są wymieniane (co wyjaśnia mój nieco dziwny porządek nazw parametrów), współrzędne są ustawione pod kątem zamiast (co wyjaśnia dwa dodatki), a współrzędne w połączonym pytaniu używają gorszego indeksowania 1. Ponieważ eliminujemy różnice, większość czasu zostaje anulowana i pozostaje nam:120∘ 90∘
Można to następnie rozegrać, zauważając, że .−⌊aj+12⌋=⌊−aj2⌋
źródło
lambda c,a,d,b:abs(a-b)+abs(a+-(c+a)/2-b--(d+b)/2)+abs((c+a)/2-(d+b)/2)
powinien zapisać 3 bajty.Pyth ,
3128 bajtówStosuje w przybliżeniu takie samo podejście, jak w odpowiedzi na pytanie w języku Python feersum . Pobiera dane wejściowe jako listę par współrzędnych, . Naprawiono błąd -1 bajtu.(x1,x2),(y1,y2)
Wypróbuj tutaj! lub Wypróbuj zestaw testowy!
Awaria
źródło
05AB1E , 16 bajtów
Korzysta ze zmodyfikowanej wersji odpowiedzi Neila , zoptymalizowanej dla języków opartych na stosie, takich jak 05AB1E. Pobiera dane wejściowe jako dwie pary współrzędnych , oddzielone znakiem nowej linii od STDIN. Początkowo połączyłem to z moją inną odpowiedzią 05AB1E, ale potem postanowiłem opublikować ją osobno, ponieważ jest bardzo, bardzo inna.(x1,x2),(y1,y2)
Wypróbuj online! lub Wypróbuj zestaw testowy! (Używa nieco zmodyfikowanej wersji kodu (
®
zamiast²
), dzięki uprzejmości Kevina Cruijssena )źródło
©+®
naDŠ+
łatwiej skonfigurować zestaw testowy. ;) Oto ten zestaw testów i wszystkie przypadki testowe rzeczywiście się powiodły (zignoruj niechlujny nagłówek; p).Galaretka ,
22 .. 1615 bajtówWypróbuj online!
Wypróbuj wszystkie przypadki testowe.
Używa metody @ Neila w tej odpowiedzi, która wykorzystuje zmodyfikowaną formułę z tego pytania matematycznego.
Przyjmuje współrzędne jako argumenty
y1, y2
ix1, x2
.źródło
Java 8,
157190188144142141127 bajtów+33 bajtów (157 → 190) z powodu poprawki błędu.
-44 bajty (188 → 144) konwertuje metodę rekurencyjną na pojedynczą metodę zapętlania.
-14 bajtów dzięki @ceilingcat .
Wyjaśnienie:
Wypróbuj tutaj.
źródło
z*z<c*c
zamiast(z<0?-z:z)<(c<0?-c:c)