Finde die Nachbarn der Zelle

20

... oder Toroidal Moore Nachbarschaften

Angesichts positive ganze Zahlen sind h, wund eine nicht negative ganze Zahl i, kehren alle Indizes umgibt i.

Sie müssen eine Matrix annehmen, die aus hZeilen von wElementen besteht, die von der niedrigsten in der oberen linken Ecke bis zur höchsten in der unteren rechten Ecke nummeriert sind, und in einem angemessenen Format eine Liste der entsprechenden Indizes zurückgeben umgeben den Index i. Diese Matrix ist ein Torus (eine unendliche Karte, die sich um jede Kante wickelt).

Zum Beispiel würden Eingaben h=4und zu folgender w=4Matrix führen:

 0  1  2  3 
 4  5  6  7
 8  9 10 11
12 13 14 15

aber genauer:

15 12 13 14 15 12
 3  0  1  2  3  0
 7  4  5  6  7  4
11  8  9 10 11  8
15 12 13 14 15 12
 3  0  1  2  3  0

so dass , wenn iwar 0, würde müssen Sie zurückkommen 15, 12, 13, 3, 1, 7, 4, 5(0-basiert).

Beispiele

0-basiert:

h   w   i       Expected result

4   4   5       0, 1, 2, 4, 6, 8, 9, 10
4   4   0       15, 12, 13, 3, 1, 7, 4, 5
4   5   1       15, 16, 17, 0, 2, 5, 6, 7
1   3   2       1, 2, 0, 1, 0, 1, 2, 0
1   1   0       0, 0, 0, 0, 0, 0, 0, 0

1-basiert:

h   w   i       Expected result

4   4   6       1, 2, 3, 5, 7, 9, 10, 11
4   4   1       16, 13, 14, 4, 2, 8, 5, 6
4   5   2       16, 17, 18, 1, 3, 6, 7, 8
1   3   3       2, 3, 1, 2, 1, 2, 3, 1
1   1   1       1, 1, 1, 1, 1, 1, 1, 1

Regeln

  • Ihre Antwort kann 0 oder 1-indiziert sein, Ihre Wahl, bitte spezifizieren.
  • Das können Sie annehmen i < h * w(oder i <= h * wfür 1-indizierte Antworten).
  • Das können Sie annehmen i >= 0(oder i > 0für 1-indizierte Antworten).
  • Die Reihenfolge der zurückgegebenen Werte ist nicht wichtig, solange nur die acht gewünschten Werte enthalten sind.
  • Standardlücken sind verboten .
  • Das ist also gewinnt die kürzeste Antwort in jeder Sprache!

Vielen Dank an @Conor O'Brien für den technischeren Titel und @ngm für mehr Testfälle!

Dom Hastings
quelle
3
Dürfen wir eine 3-mal-3-Matrix von Nachbarn zurückgeben?
Adám
@ Adám Ich würde es vorziehen, wenn die Liste die mittlere Zelle nicht enthält, wenn möglich. Aber zu schätzen gibt es schon Antworten. Ist es einfach genug, dies herauszufiltern?
Dom Hastings
Kommt es auf die Bestellung an?
Robert Fraser
@RobertFraser Reihenfolge ist nicht wichtig. Ich werde das zu den Regeln hinzufügen.
Dom Hastings
@DomHastings Ich interpretiere diesen Kommentar als: Es ist nicht erlaubt, eine 3 x 3-Matrix zurückzugeben oder die mittlere Zelle einzuschließen.
JungHwan Min

Antworten:

8

JavaScript (ES6), 75 Byte

2 Bytes dank @KevinCruijssen gespeichert

Erwartet einen 0-basierten Index.

(h,w,i)=>[...'12221000'].map((k,j,a)=>(i+w+~-k)%w+~~(i/w+h+~-a[j+2&7])%h*w)

Probieren Sie es online!

Die umgebenden Indizes werden in der folgenden Reihenfolge zurückgegeben:

54362701

Wie?

Die Indizes jeder umgebenden Zelle bei sind gegeben durch: ( x + d x , y + d y )ichdx,dy(x+dx,y+dy)

Idx,dy=((x+dx)modw)+w((y+dy)modh)=((N+dx)modw)+w((Nw+dy)modh)

Dabei ist der Index der Zielzelle.N=wy+x

Wir gehen die Liste und subtrahieren , um den Wert von , der ergibt:1 d x[1,2,2,2,1,0,0,0]1dx

[0,1,1,1,0,-1,-1,-1]

Für die entsprechenden Werte von wir dieselbe Liste, die um zwei Positionen verschoben ist. ergibt:dy

[1,1,0,-1,-1,-1,0,1]
Arnauld
quelle
w*(~~(i/w+h+~-a[j+2&7])%h)um ~~(a[j+2&7]-1+i/w+h)%h*w2 Bytes zu sparen, indem ein Klammerpaar entfernt wird.
Kevin Cruijssen
@ KevinCruijssen Schöner Fang. Vielen Dank!
Arnauld
6

APL (Dyalog Classic) , 27 Byte

{(⍺⊥⍺|(⍺⊤⍵)-⊢)¨1-14⌽,⍳3 3}

Probieren Sie es online!

{ }ist eine Funktion mit Argumenten (den Dimensionen h w) und (dem Index i)

⍳3 3ist eine Matrix aller 2-stellige ternärer Zahlen: 0 0, 0 1, ...,2 2

, trägt die Matrix als Vektor ein

1↓4⌽Entfernt das mittlere Element, 1 1indem Sie 4 nach links drehen ( 4⌽) und eins fallen lassen ( 1↓).

1- subtrahiert von 1 und gibt alle 8 Nachbarversätze an

( Wendet den Funktionszug in Klammern auf jeden Versatz an

⍺⊤⍵ist die Basiscodierung von - den Koordinaten in der Matrix

(⍺⊤⍵)-⊢ subtrahiert den aktuellen Versatz und gibt die Koordinaten eines Nachbarn an

⍺|ist ein Mod a, der Koordinaten umfließt und in der Matrix bleibt

⍺⊥ decodiert von der Basis

ngn
quelle
5

APL (Dyalog Unicode) , 40 Byte SBCS

Anonyme Infix-Funktion. Nimmt h wals linkes Argument und ials rechtes Argument.

{14⌽,3 3↑,⍨⍣2⍪⍨⍣2⊃⊖∘⍉/(¯1+⍺⊤⍵),⊂⍺⍴⍳×/⍺}

Probieren Sie es online!

{... } "dfn"; ist linkes Argument (Dimensionen) und rechtes Argument (Index).

×/⍺ Produkt (Multiplikation-Reduktion) der Dimensionen

 der erste, der viele indizes

⍺⍴ Verwenden Sie die Dimensionen, um das umzugestalten

 schließe es ein (um es als ein einzelnes Element zu behandeln)

(), Folgendes voranstellen:

  ⍺⊤⍵ Kodiere den Index in Mixed-Radix h w(dies gibt uns die Koordinaten des Index)

  ¯1+ Fügen Sie diesen Koordinaten eine negative hinzu

⊖∘⍉/ Reduzieren durch Drehen-der-Transponieren
  ist gleichbedeutend mit y⊖⍉x⊖⍉... was gleichbedeutend mit y⊖x⌽... ist, das so viele Schritte inach links dreht, wie nach rechts versetzt sind (weniger als einer), und so viele Schritte nach oben dreht, wie nach iunten versetzt sind (weniger als einer) Die 3-mal-3-Matrix soll sich in der oberen linken Ecke befinden

 offenbaren (weil die Reduktion den Vektor durch Einschließen auf Skalar reduzierte)

⍪⍨⍣2 zweimal auf sich selbst stapeln (wir brauchen wirklich nur dreimal für einreihige Matrizen)

,⍨⍣2 hängt sich zweimal an (wir brauchen wirklich nur dreimal für einspaltige Matrizen)

3 3↑ nimm die ersten drei Zeilen der ersten drei Spalten

Die nächsten beiden Schritte können weggelassen werden, wenn die Rückgabe einer 3-mal-3-Matrix akzeptabel ist:

, Ravel (Abflachen)

4⌽ Vier Schritte nach links drehen (bringt das mittlere Element nach vorne)

1↓ Lassen Sie das erste Element fallen

Adam
quelle
@Adám behebe das obige und verkürze es: {,(⍺⊥⍺|(⍺⊤⍵)-⊢)¨1-⍳3 3}Ich bin mir nicht sicher, ob du auch das mittlere Element entfernen {4⌽1↓4⌽}
solltest
@ngn Äh, das ist ziemlich originell. Du postest das!
Adám
@ Adám ok
ngn
Ich glaube nicht, dass erwartet wird, dass die Ausgabe das zentrale Element enthält.
JungHwan Min 18.07.18
1
Der letzte Testfall hat noch 8 Elemente. Ich denke, die beabsichtigte Ausgabe ist es, die Nachbarn an relativen Positionen zu drucken[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]
JungHwan Min
4

Python 2 , 79 69 66 Bytes

lambda h,w,i:[(i+q%3-1)%w+(i/w+q/3-1)%h*w for q in range(9)if q-4]

Probieren Sie es online!

3 Bytes geschenkt von Neil , der das bemerkt (x*w)%(h*w)==((x)%h)*w==(x)%h*w.

0-indizierte Lösung.

Chas Brown
quelle
%h*w Spart 3 Bytes über *w%(h*w).
Neil
4

R , 125 111 108 Bytes

function(x,i,m=array(1:prod(x),x),n=rbind(m,m,m),o=cbind(n,n,n),p=which(m==i,T)+x-1)o[p[1]+0:2,p[2]+0:2][-5]

Probieren Sie es online!

14 und 8 Bytes von @JayCe und @Mark.

Die Eingabe erfolgt, [w, h], iweil R zuerst die Spalte der Arrays ausfüllt.

Macht das Array und "verdreifacht" es dann zeilen- und spaltenweise. iSuchen Sie dann im ursprünglichen Array und finden Sie dessen Nachbarschaft. Ausgabe ohne i.

ngm
quelle
1
Sie können 14 Bytes sparen . Ich wusste nicht, dass das, was ein arr.ind-Argument hatte, heute etwas gelernt hat!
JayCe
Sie können sparen 8 Bytes durch den Austausch seq()mit1:
Mark
3

PHP , 165 Bytes

Dies ist "0-basiert". Es muss eine bessere Lösung in PHP geben, aber dies ist ein Ausgangspunkt!

<?list(,$h,$w,$i)=$argv;for($r=-2;$r++<1;)for($c=-2;$c++<1;)$r||$c?print(($k=(int)($i/$w)+$r)<0?$h-1:($k>=$h?0:$k))*$w+(($l=$i%$w+$c)<0?$w-1:($l>=$w?0:$l))%$w.' ':0;

Um es auszuführen:

php -n <filename> <h> <w> <i>

Beispiel:

php -n cell_neighbours.php 4 5 1

Oder versuchen Sie es online!

Night2
quelle
3

K (NGN / k) , 27 24 Bytes

{x/x!''(x\y)-1-3\(!9)^4}

Probieren Sie es online!

{ }ist eine Funktion mit Argumenten x(den Dimensionen h w) und y(dem Index i)

(!9)^4ist 0 1 2 3 4 5 6 7 8ohne die4

3\ codiert in ternary: (0 0;0 1;0 2;1 0;1 2;2 0;2 1;2 2)

1-subtrahiert von 1und gibt benachbarte Offsets:(1 1;1 0;1 -1;0 1;0 -1;-1 1;-1 0;-1 -1)

x\yist die Basiscodierung xvon y- den Koordinaten yin der Matrix

- subtrahiert jeden Versatz und gibt uns 8 Paare von Nachbarkoordinaten

x!''is mod xfor each - Koordinaten umlaufen, um in der Matrix zu bleiben

x/decodiert von der Basis x- wandelt Koordinatenpaare in einzelne Ganzzahlen um

ngn
quelle
Hat Ihre Variante von K aus Neugierde ein Adverb mit "umgekehrten Argumenten" wie das von J ~?
Conor O'Brien
1
@ ConorO'Brien Keines der mir bekannten ks (Kx's K, Kona, oK und meins) hat es, was zum Golfen unglücklich ist. Es gibt nur 6 eingebaute Adverbien: / \ '/: \:': und keinen Mechanismus für benutzerdefinierte wie.
ngn
Natürlich könnte ich ein Selfie-Adverb hinzufügen, aber Golfen ist für ngn / k kein Selbstzweck, sondern nur ein Mittel, um Testfälle und Erfahrungen zu sammeln.
ngn
Das ist fair. Natürlich könnte man es als ein mögliches Manko der Sprache ansehen. Ich habe PPCG verwendet, um Attache zu entwickeln, und festgestellt, dass Attache einige sehr nützliche Funktionen fehlten, die ich sonst nicht enthalten hätte. Ich benutze kein K, aber vielleicht gibt es andere Verwendungszwecke, die diese Art von Adverb rechtfertigen könnten?
Conor O'Brien
@ ConorO'Brien Ich kenne mich in APL aus, das ist wie ~in J, und ich bin von seiner Nützlichkeit überzeugt, aber Sie sehen, k ist auf druckbares ASCII und (fast) keine Digraphen beschränkt, also würde ein neues Adverb bedeuten das Opfer eines anderen nützlichen Grundelements sowie mehr Inkompatibilität zwischen Implementierungen. Ich verstehe nicht, was ich tun kann, um dies zu tun.
ngn
2

MATL , 24 Bytes

*:2Geti=&fh3Y6&fh2-+!Z{)

Die Eingänge sind h, w, i. Die Ausgabe ist ein Zeilen- oder Spaltenvektor mit den Zahlen.

Eingang iund Ausgang sind 1-basiert.

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

*     % Take two inputs implicitly. Multiply
      % STACK: 16
:     % Range
      % STACK: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
2G    % Push second input again
      % STACK: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], 4
e     % Reshape with that number of rows, in column-major order
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16]
t     % Duplicate
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16],
      %        [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16]
i=    % Take third input and compare, element-wise
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16],
      %        [0 0 0 0; 0 1 0 0; 0 0 0 0; 0 0 0 0]
&f    % Row and column indices of nonzeros (1-based)
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16], 2, 2,
h     % Concatenate horizontally
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16], [2 2]
3Y6   % Push Moore mask
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16], [2 2],
      %        [1 1 1; 1 0 1; 1 1 1]
&f    % Row and column indices of nonzeros (1-based)
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16], [2 2],
      %        [1; 2; 3; 1; 3; 1; 2; 3], [1; 1; 1; 2; 2; 3; 3; 3] 
h     % Concatenate horizontally
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16], [2 2],
      %        [1 1; 2 1; 3 1; 1 2; 3 2; 1 3; 2 3; 3 3] 
2-    % Subtract 2, element-wise
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16], [2 2],
      %        [-1 -1; 0 -1; 1 -1; -1 0; -1 0; -1 1; 0 1; 1 1] 
+     % Add, element-wise with broadcast
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16],
      %        [1 1; 2 1; 3 1; 1 2; 3 2; 1 3; 2 3; 3 3]
!     % Transpose
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16],
      %        [1 2 3 1 3 1 2 3; 1 1 1 2 2 3 3 3]
Z{    % Convert into a cell array of rows
      % STACK: [1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16],
      %        {[1 2 3 1 3 1 2 3], [1 1 1 2 2 3 3 3]}
)     % Index. A cell array acts as an element-wise (linear-like) index
      % STACK: [1 2 3 5 7 9 10 11]
Luis Mendo
quelle
2

Batch, 105 Bytes

@for /l %%c in (0,1,8)do @if %%c neq 4 cmd/cset/a(%3/%2+%1+%%c/3-1)%%%1*%2+(%3%%%2+%2+%%c%%3-1)%%%2&echo.

0-indiziert. 23 Bytes durch Stehlen von @ ChasBrowns Modulo 3-Trick gespart.

Neil
quelle
2

MATL, 24 Bytes

X[h3Y6&fh2-+1GX\1Gw!Z}X]

Probieren Sie es auf MATL Online aus

Übernimmt Eingaben [w h]und i. 8 Bytes davon wurden schamlos von Luis Mendos 'Antwort gestohlen , obwohl der Gesamtansatz anders ist.

Sundar - Setzen Sie Monica wieder ein
quelle
1

Sauber , 85 83 Bytes

import StdEnv
r=(rem)
$h w i=tl[r(n+i/w)h*w+r(r(m+i)w)w\\n<-[0,1,h-1],m<-[0,1,w-1]]

Probieren Sie es online!

Wird ials Koordinate behandelt (0 <= p < h, 0 <= q < w)und generiert die Werte der angrenzenden Elemente, in denen sich der Wert befindet p'w + q'.

Οurous
quelle
1

Gelee , 20 Bytes

PRs©Ṫ{œi+€Ø-Ż¤ŒpḊœị®

Ein dyadischer Link, der eine Liste der Dimensionen auf der linken Seite [h,w]und die Zelle als Ganzzahl auf der rechten Seite akzeptiert i, die eine Liste der Nachbarschaft ergibt.

Hinweis: Die Reihenfolge unterscheidet sich von der in den Beispielen, die im OP zulässig sind

Probieren Sie es online!

Wie?

PRs©Ṫ{œi+€Ø-Ż¤ŒpḊœị® - Link: [h,w], i
P                    - product -> h*w
 R                   - range -> [1,2,3,...,h*w]
    Ṫ{               - tail of left -> w
  s                  - split into chunks -> [[1,2,3,...w],[w+1,...,2*w],[(h-1)*w+1,...,h*w]]
   ©                 - ...and copy that result to the register
      œi             - multi-dimensional index of (i) in that list of lists, say [r,c]
             ¤       - nilad followed by link(s) as a nilad:
          Ø-         -   literal list -> [-1,1]
            Ż        -   prepend a zero -> [0,-1,1]
        +€           - addition (vectorises) for €ach -> [[r,r-1,r+1],[c,c-1,c+1]]
              Œp     - Cartesian product -> [[r,c],[r,c-1],[r,c+1],[r-1,c],[r-1,c-1],[r-1,c+1],[r+1,c],[r+1,c-1],[r+1,c+1]]
                Ḋ    - dequeue -> [[r,c-1],[r,c+1],[r-1,c],[r-1,c-1],[r-1,c+1],[r+1,c],[r+1,c-1],[r+1,c+1]]
                   ® - recall (the table) from the register
                 œị  - multi-dimensional index into (1-indexed & modular)
Jonathan Allan
quelle
1

Attache , 66 Bytes

{a.=[]Moore[Integers@@__2,{Push[a,_]},cycle->1]Flat[a@_][0:3'5:8]}

Probieren Sie es online!

Ich muss noch implementieren Mooresund NMoore, aber ich habe immer noch Mooredie als Iterationsfunktion dient. Erstellt im Wesentlichen Integers@@__2ein ganzzahliges Shape-Array __2(die letzten beiden Argumente) der ersten Prod[__2]Ganzzahlen. Dies gibt uns das Ziel-Array. Anschließend Mooreiteriert die Funktion {Push[a,_]}über jede Moore-Nachbarschaft der Größe 1(implizites Argument) mit der Option, jedes Element ( cycle->1) zu durchlaufen . Dadurch wird jede Nachbarschaft zum Array hinzugefügt a. Dann wird Flat[a@_]das _dritte Mitglied , dh das aum das Moore-Viertel zentrierte, abgeflacht _(das erste Argument). [0:3'5:8]Ruft alle Elemente mit Ausnahme der Mitte aus diesem abgeflachten Array ab.

Diese Lösung mit einer Aktualisierung der Sprache würde ungefähr so ​​aussehen (49 Byte):

{Flat[NMoore[Integers@@__2,_,cycle->1]][0:3'5:8]}
Conor O'Brien
quelle
1

Kotlin , 88 Bytes

Verwendet nullbasierte Indizes und gibt eine Liste mit 8 Elementen aus.

{h:Int,w:Int,i:Int->List(9){(w+i+it%3-1)%w+(h+i/w+it/3-1)%h*w}.filterIndexed{i,v->i!=4}}

Probieren Sie es online!

JohnWells
quelle