Bardzo powszechną potrzebą w klasach algorytmów i informatyce jest iteracja 4-kierunkowo po siatce lub macierzy (np. W BFS lub DFS). Wydaje się, że często powoduje to dużo nieporęcznego i pełnego kodu z dużą ilością arytmetyki i porównań w pętlach. Widziałem wiele różnych podejść do tego, ale nie mogę pozbyć się wrażenia, że istnieje bardziej zwięzły sposób na zrobienie tego.
Wyzwanie polega na napisaniu czystej funkcji, która biorąc pod uwagę szerokość i wysokość skończonej płaszczyzny n, m
rozpoczynającej się w punkcie (0,0)
oraz współrzędne, (x,y)
które mogą reprezentować dowolny ważny punkt w tej płaszczyźnie, zwraca iterowalny obiekt wszystkich punktów w płaszczyźnie, które są 4-kierunkowo przylegające do (x,y)
.
Celem jest zdefiniowanie tej funkcji w jak najmniejszej liczbie bajtów.
Kilka przykładów, które pomogą zilustrować prawidłowe dane wejściowe / wyjściowe:
n = 5 (y-axis), m = 3 (x-axis) (zero-based)
matrix = [
[A, B, C],
[D, E, F],
[G, H, I],
[J, K, L],
[M, N, O],
]
(x, y) => [valid iterable points]
E: (1, 1) => [(1, 0), (2, 1), (1, 2), (0, 1)]
A: (0, 0) => [(1, 0), (0, 1)]
L: (2, 3) => [(2, 2), (2, 4), (1, 3)]
N: (1, 4) => [(1, 3), (2, 4), (0, 4)]
n = 1 (y-axis), m = 1 (x-axis) (zero-based)
matrix = [
[A],
]
(x, y) => [valid iterable points]
A: (0, 0) => []
n = 2 (y-axis), m = 1 (x-axis) (zero-based)
matrix = [
[A],
[B],
]
(x, y) => [valid iterable points]
A: (0, 0) => [(0, 1)]
B: (0, 1) => [(0, 0)]
A oto przykład (ten w Pythonie) funkcji spełniającej warunki:
def four_directions(x, y, n, m):
valid_coordinates = []
for xd, yd in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
nx, ny = x + xd, y + yd
if 0 <= nx < m and 0 <= ny < n:
valid_coordinates.append((nx, ny))
return valid_coordinates
W powyższym przykładzie zdefiniowano nazwaną funkcję, ale dopuszczalne są również funkcje anonimowe.
Wszystkie dane wejściowe n, m, x, y
są 32-bitowymi liczbami całkowitymi bez znaku w następujących zakresach:
n > 0
m > 0
0 <= x < m
0 <= y < n
Wynik musi mieć postać iterowalnej (jednak wybrany przez Ciebie język to określa) par (x, y).
Dodatkowe wyjaśnienia:
Liczby zespolone (i inne reprezentacje / serializacje) są w porządku, o ile konsument iterowalnego może uzyskać dostęp x
i y
jako liczby całkowite znające tylko ich lokalizację.
Indeksy niezerowe są dopuszczalne, ale tylko wtedy, gdy wybranym językiem jest język niezerowy. Jeśli język używa kombinacji systemów numerowania, domyślnie jest to system numeracji struktury danych najczęściej używany do reprezentacji macierzy. Jeśli nadal są to wszystkie obce pojęcia w danym języku, dopuszczalny jest każdy indeks początkowy.
(x,y)
sam jest w prostokącie, prawda?Odpowiedzi:
Python 2 , 66 bajtów
Wypróbuj online!
Wyświetla listę czterech sąsiadów, a następnie używa wycinania listy, aby usunąć te, które są poza granicami.
Python 2 , 71 bajtów
Wypróbuj online!
Zamiast sprawdzać, który z czterech sąsiadów znajduje się w granicach, robimy to w wolniejszy sposób, sprawdzając wszystkie punkty w granicach dla tych, którzy są sąsiadami, czyli mają odległość euklidesową dokładnie 1 od
(x,y)
. Używamy również klasycznej sztuczki div-mod do iteracji po siatce , co pozwala uniknąć konieczności pisania dwóch pętlifor i in range(m)for j in range(n)
.Próbowałem użyć złożonej arytmetyki do napisania warunku odległości, ale okazało się, że pisanie trwało dłużej
abs((k/n-x)*1j+k%n-y)==1
.Python 2 , 70 bajtów
Wypróbuj online!
źródło
Oktawa , 90 bajtów
Wykorzystuje to podejście geometryczne: Najpierw tworzymy macierz zer o pożądanym rozmiarze i ustawiamy
1
na pożądaną lokalizację. Następnie łączymy się z jądremktóra tworzy nową macierz tego samego rozmiaru z macierzami u 4 sąsiadów pierwotnego punktu. Następnie mamy
find()
indeksy niezerowych wpisów tej nowej macierzy.Wypróbuj online!
splot jest kluczem do sukcesu.
źródło
Wolfram Language (Mathematica) , 42 bajty
Wypróbuj online!
1-indeksowany (zgodnie z konwencją Mathematica dotyczącą indeksowania). Pobiera dane wejściowe jako
{x,y}, {m,n}
.dla We / Wy indeksowanych 0, 45 bajtów :
Wypróbuj online!
źródło
JavaScript (ES6), 74 bajty
Nudne podejście.
Wypróbuj online!
JavaScript (Node.js) , 74 bajty
Mniej nudne, ale równie długie. Pobiera dane wejściowe jako
([h,w,x,y])
.Wypróbuj online!
JavaScript (V8) , 67 bajtów
Gdyby dozwolone były wszystkie standardowe metody wyjściowe, moglibyśmy po prostu wydrukować prawidłowe współrzędne za pomocą:
Wypróbuj online!
źródło
Galaretka ,
1312 bajtówDwójkowym link przyjmując listę dwóch (0 indeksowane) liczb po lewej stronie,
[row, column]
i dwie liczby po prawej stronie[height, width]
, co daje listę list liczb całkowitych[[adjacent_row_1, adjacent_column_1], ...]
.Wypróbuj online!
W jaki sposób?
źródło
ḶṚƬ
zṬ€
.2ḶṚƬNƬẎ
zwraca[[0, 1], [1, 0], [0, -1], [-1, 0]]
, podczas gdy2Ṭ€NƬẎ
zwraca[[1], [0, 1], [-1], [0, -1]]
, a ponieważ singletony są opakowane,+
wektoryzuje tylko pierwszy element⁸
dla tych, więc działają tak, jakby ich drugim elementem była0
(tożsamość addytywna). W rezultacie zmieni się tylko kolejność danych wyjściowych.Perl 6 ,
5649 bajtów-7 bajtów dzięki nwellnhof!
Wypróbuj online!
Usuwa elementy poza granicami, sprawdzając, czy po podzieleniu przez granice tablicy wynosi od 0 do 1. Pobiera dane wejściowe i wyjściowe za pomocą liczb zespolonych, w których rzeczywista część jest
x
współrzędną, a urojonąy
. Możesz je wyodrębnić za pomocą funkcji.im
i.re
.źródło
div
nie wydaje się do pracy dlaNum
S(*.reals>>.Int Zdiv@^b).none
lub(*.reals Z/@^b)>>.Int.none
zadziałałoby, ale obsada wydaje się zbyt kosztowna.J ,
302928 bajtówWypróbuj online!
W jaki sposób:
m
xn
arg w siatkę liczb zespolonychj./&i./
j./
1=|@-
#~&,
+.@
źródło
C # (interaktywny kompilator Visual C #) , 91 bajtów
Wypróbuj online!
Alternatywnie:
Wypróbuj online!
źródło
Węgiel drzewny , 29 bajtów
Wypróbuj online! Link jest do pełnej wersji kodu. Pobiera dane wejściowe w kolejności x, y, szerokość, wysokość. Wyjaśnienie:
Wydrukuj
#
w podanej pozycji.Pętla nad danym prostokątem.
Przejdź do bieżącej pozycji.
Jeśli jest sąsiad,
#
zapisz pozycję.Wyjście wykrytych pozycji na końcu pętli.
Nudna odpowiedź:
Wypróbuj online! Link jest do pełnej wersji kodu. Działa poprzez znalezienie matematycznie sąsiednich pozycji.
źródło
Haskell, 62 bajty
Za pomocą
Wypróbuj online!
Nudne podejście: 81 bajtów
źródło