In Algorithmenklassen und in der Informatik im Allgemeinen besteht eine sehr häufige Anforderung darin, über ein Gitter oder eine Matrix (wie in BFS oder DFS) in vier Richtungen zu iterieren. Dies scheint oft zu viel klobigem und ausführlichem Code mit viel Arithmetik und Vergleichen innerhalb von Schleifen zu führen. Ich habe viele verschiedene Ansätze gesehen, aber ich kann das Gefühl nicht loswerden, dass es einen präziseren Weg gibt, dies zu tun.
Die Herausforderung besteht darin, eine reine Funktion zu schreiben, die unter Berücksichtigung der Breite und Höhe einer endlichen Ebene mit n, m
Ursprung in einem Punkt (0,0)
und der Koordinaten (x,y)
, die einen gültigen Punkt in dieser Ebene darstellen können, ein iterierbares Objekt aller Punkte in der Ebene mit vier Richtungen zurückgibt angrenzend an (x,y)
.
Ziel ist es, diese Funktion in möglichst wenigen Bytes zu definieren.
Einige Beispiele zur Veranschaulichung der gültigen Eingabe / Ausgabe:
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)]
Und hier ist ein Beispiel (dieses in Python) für eine Funktion, die die folgenden Bedingungen erfüllt:
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
Im obigen Beispiel wurde eine benannte Funktion definiert, aber auch anonyme Funktionen sind zulässig.
Die Eingaben n, m, x, y
sind alle vorzeichenlose 32-Bit-Ganzzahlen in den folgenden Bereichen:
n > 0
m > 0
0 <= x < m
0 <= y < n
Die Ausgabe muss die Form eines iterablen (wie auch immer Ihre gewählte Sprache dies definiert) von (x, y) Paaren haben.
Zusätzliche Erläuterungen:
Komplexe Zahlen (und andere Darstellungen / Serialisierungen) sind in Ordnung, solange der Konsument des Iterablen auf sie zugreifen kann x
und y
als ganze Zahlen nur ihren Standort kennen.
Nicht auf Null basierende Indizes sind zulässig, jedoch nur, wenn die gewählte Sprache eine nicht auf Null basierende Sprache ist. Wenn die Sprache eine Mischung aus Nummerierungssystemen verwendet, wird standardmäßig das Nummerierungssystem der Datenstruktur verwendet, die am häufigsten zur Darstellung einer Matrix verwendet wird. Wenn dies immer noch alles fremde Begriffe in der angegebenen Sprache sind, ist jeder Startindex akzeptabel.
(x,y)
sich um ein Rechteck handelt, oder?Antworten:
Python 2 , 66 Bytes
Probieren Sie es online!
Listet die vier Nachbarn auf und entfernt dann mit List Slicing diejenigen, die außerhalb der Grenzen liegen.
Python 2 , 71 Bytes
Probieren Sie es online!
Anstatt zu prüfen, welche der vier Nachbarn eingegrenzt sind, prüfen wir langsamer alle eingegrenzten Punkte für diejenigen, die Nachbarn sind, dh von denen der euklidische Abstand genau 1 beträgt
(x,y)
. Wir verwenden auch den klassischen Div-Mod-Trick, um über ein Gitter zu iterieren , ohne zwei Schleifen schreiben zu müssenfor i in range(m)for j in range(n)
.Ich habe versucht, die Entfernungsbedingung mit komplexer Arithmetik zu schreiben, aber es stellte sich heraus, dass das Schreiben länger dauert
abs((k/n-x)*1j+k%n-y)==1
.Python 2 , 70 Bytes
Probieren Sie es online!
quelle
Oktave , 90 Bytes
Hierbei wird ein geometrischer Ansatz verwendet: Zuerst erstellen wir eine Matrix aus Nullen der gewünschten Größe und setzen a
1
auf die gewünschte Position. Dann falten wir uns mit dem Kernel zusammenDadurch wird eine neue Matrix derselben Größe mit einer Matrix an den vier Nachbarn des ursprünglichen Punkts erstellt. Dann werden
find()
die Indizes der Nicht-Null-Einträge dieser neuen Matrix berechnet.Probieren Sie es online!
Faltung ist der Schlüssel zum Erfolg.
quelle
Wolfram Language (Mathematica) , 42 Byte
Probieren Sie es online!
1-indiziert (gemäß der Konvention von Mathematica für die Indizierung). Übernimmt die Eingabe als
{x,y}, {m,n}
.für 0-indizierte E / A, 45 Bytes :
Probieren Sie es online!
quelle
JavaScript (ES6), 74 Byte
Langweiliger Ansatz.
Probieren Sie es online!
JavaScript (Node.js) , 74 Byte
Weniger langweilig aber genauso lang. Übernimmt die Eingabe als
([h,w,x,y])
.Probieren Sie es online!
JavaScript (V8) , 67 Byte
Wenn alle Standardausgabemethoden erlaubt wären, könnten wir einfach die gültigen Koordinaten ausdrucken mit:
Probieren Sie es online!
quelle
Jelly ,
1312 BytesEine dyadische Link - Liste zwei (0 indizierte) ganze Zahlen auf der linken Seite, der Annahme
[row, column]
und zwei ganzen Zahlen auf der rechten Seite[height, width]
, die eine Liste von Listen von ganzen Zahlen ergibt[[adjacent_row_1, adjacent_column_1], ...]
.Probieren Sie es online!
Wie?
quelle
ḶṚƬ
mitṬ€
.2ḶṚƬNƬẎ
return[[0, 1], [1, 0], [0, -1], [-1, 0]]
, while2Ṭ€NƬẎ
return[[1], [0, 1], [-1], [0, -1]]
und da die Singletons umgebrochen sind,+
vektorisieren sie nur mit dem ersten Element von⁸
für diejenigen, so dass sie so tun, als ob ihr zweites Element0
(die additive Identität) ist. Infolgedessen kann sich nur die Reihenfolge der Ausgabe ändern.Perl 6 ,
5649 Bytes-7 bytes dank nwellnhof!
Probieren Sie es online!
Entfernt die Out-of-Bound-Elemente, indem überprüft wird, ob sie bei Division durch die Array-Grenzen zwischen 0 und 1 liegen. Nimmt die Eingabe und Ausgabe über komplexe Zahlen vor, bei denen der Realteil der ist
x
Koordinate und der Imaginärteil Koordinate isty
. Sie können diese mit den Funktionen.im
und extrahieren.re
.quelle
div
scheint nicht zu Arbeit fürNum
s(*.reals>>.Int Zdiv@^b).none
oder(*.reals Z/@^b)>>.Int.none
würde funktionieren, aber der Int-Cast scheint zu teuer.J ,
302928 BytesProbieren Sie es online!
Wie:
m
xn
arg in ein Gitter komplexer Zahlenj./&i./
j./
1=|@-
#~&,
+.@
quelle
C # (Visual C # Interactive Compiler) , 91 Byte
Probieren Sie es online!
Alternative:
Probieren Sie es online!
quelle
Kohle , 29 Bytes
Probieren Sie es online! Link ist eine ausführliche Version des Codes. Übernimmt Eingaben in der Reihenfolge x, y, width, height. Erläuterung:
Drucken Sie a
#
an der angegebenen Position aus.Bewegen Sie sich über das angegebene Rechteck.
Zur aktuellen Position springen.
Wenn es einen Nachbarn gibt,
#
speichern Sie die Position.Die erkannten Positionen am Ende der Schleife ausgeben.
Langweilige Antwort:
Probieren Sie es online! Link ist eine ausführliche Version des Codes. Funktioniert durch mathematisches Finden der angrenzenden Positionen.
quelle
Haskell, 62 Bytes
Verwenden
Probieren Sie es online!
Langweiliger Ansatz: 81 Bytes
quelle