Encontre os vizinhos da célula

20

... ou Bairros Toroidal Moore

Inteiros positivos dadas h, we um número inteiro não negativo i, voltar todos os índices circundantes i.

Você deve assumir uma matriz composta por hlinhas de welementos, numeradas do mais baixo, no canto superior esquerdo, ao mais alto, no canto inferior direito, e retornar, em qualquer formato razoável, uma lista dos índices que rodeie o índice i. Essa matriz é um toro (um mapa infinito que envolve cada borda).

Por exemplo, entradas h=4e w=4, resultariam na matriz:

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

mas mais especificamente:

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

de modo que, se ifosse 0, seria necessário retornar 15, 12, 13, 3, 1, 7, 4, 5(com base em 0).

Exemplos

Baseado em 0:

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

Baseado em 1:

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

Regras

  • Sua resposta pode ser indexada em 0 ou 1, sua escolha, por favor especifique.
  • Você pode assumir isso i < h * w(ou i <= h * wpara respostas indexadas em 1).
  • Você pode assumir isso i >= 0(ou i > 0para respostas indexadas em 1).
  • A ordem dos valores retornados não é importante desde que apenas os oito valores desejados sejam incluídos.
  • As brechas padrão são proibidas .
  • Isso é então a resposta mais curta, em cada idioma, vence!

Agradecemos a @Conor O'Brien pelo título mais técnico e o @ngm por mais casos de teste!

Dom Hastings
fonte
3
Podemos retornar uma matriz 3 por 3 de vizinhos?
Adám 18/07/19
@ Adám Prefiro que a lista não inclua a célula central, se possível. Mas aprecie, já existem respostas. É fácil filtrar isso?
Dom Hastings
A ordem importa?
Robert Fraser
@RobertFraser Order não é importante. Vou adicionar isso às regras.
Dom Hastings
@DomHastings Interpreto esse comentário como: não é permitido retornar uma matriz 3 por 3 ou incluir a célula central?
JungHwan Min 18/07/19

Respostas:

8

JavaScript (ES6), 75 bytes

Guardado 2 bytes graças a @KevinCruijssen

Espera um índice baseado em 0.

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

Experimente online!

Os índices circundantes são retornados na seguinte ordem:

54362701

Quão?

Os índices Idx,dy de cada célula circundante em (x+dx,y+dy) são dados por:

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

onde é o índice da célula de destino.N=wy+x

Percorremos a lista e para obter o valor de , que fornece:[1,2,2,2,1,0,0,0]1dx

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

Para os valores correspondentes de , usamos a mesma lista deslocada em 2 posições, o que fornece:dy

[1,1,0,1,1,1,0,1]
Arnauld
fonte
w*(~~(i/w+h+~-a[j+2&7])%h)a ~~(a[j+2&7]-1+i/w+h)%h*wsalva 2 bytes por se livrar de um par de parênteses.
21818 Kevin Cruijssen
@KevinCruijssen Nice catch. Obrigado!
Arnauld
6

APL (Dyalog Classic) , 27 bytes

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

Experimente online!

{ }é uma função com argumentos (as dimensões h w) e (o índice i)

⍳3 3é uma matriz de todos os números ternários de 2 dígitos: 0 0, 0 1, ...,2 2

, inscreve a matriz como um vetor

1↓4⌽remove o elemento central 1 1girando 4 para a esquerda ( 4⌽) e soltando um ( 1↓)

1- subtrai de 1, dando todas as 8 compensações vizinhas

( aplica o trem de função entre parênteses a cada deslocamento

⍺⊤⍵é a codificação base de - as coordenadas de na matriz

(⍺⊤⍵)-⊢ subtrai o deslocamento atual, fornecendo as coordenadas de um vizinho

⍺|é mod apara envolver as coordenadas e permanecer dentro da matriz

⍺⊥ decodifica a partir da base

ngn
fonte
5

APL (Dyalog Unicode) , SBCS de 40 bytes

Função de infixo anônimo. Toma h wcomo argumento à esquerda e icomo argumento à direita.

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

Experimente online!

{... } "dfn"; é argumento à esquerda (dimensões) e é argumento à direita (índice).

×/⍺ produto (redução-multiplicação) das dimensões

 o primeiro que muitos índices

⍺⍴ utilizar as dimensões de r eshape que

 coloque-o (para tratá-lo como um único elemento)

(), Acrescente o seguinte:

  ⍺⊤⍵ codificar o índice em base mista h w(isso nos fornece as coordenadas do índice)

  ¯1+ adicione um negativo a essas coordenadas

⊖∘⍉/ reduzir girando a transposição
  é equivalente a y⊖⍉x⊖⍉... o que equivale a y⊖x⌽... que gira para a esquerda quantas etapas ié deslocada para a direita (menos uma) e gira para cima quantas etapas ié deslocada para baixo (menos uma), causando a matriz 3 por 3, procuramos estar no canto superior esquerdo

 divulgar (porque a redução reduziu o vetor a escalar ao encerrar)

⍪⍨⍣2 empilhar duas vezes em cima de si mesmo (só precisamos realmente três vezes para matrizes de linha única)

,⍨⍣2 anexar a si mesmo duas vezes (precisamos apenas três vezes para matrizes de coluna única)

3 3↑ pegue as três primeiras linhas das três primeiras colunas

As próximas duas etapas podem ser omitidas se o retorno de uma matriz 3 por 3 for aceitável:

, ravel (achatar)

4⌽ gire quatro etapas para a esquerda (traz o elemento central para a frente)

1↓ solte o primeiro elemento

Adão
fonte
@ Adám corrigir o exposto, e reduzi-lo: {,(⍺⊥⍺|(⍺⊤⍵)-⊢)¨1-⍳3 3}, eu não tenho certeza se você também deve remover o elemento do meio: {4⌽1↓4⌽...}
NGN
@ng Uh, isso é bastante original. Você publica isso!
Adám 18/07/19
@ Adám ok
ngn
Eu não acho que a saída deva ter o elemento central nela.
JungHwan Min
1
O último caso de teste ainda possui 8 elementos. Eu acho que o resultado pretendido é imprimir os vizinhos em posições relativas[-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]

Experimente online!

3 bytes dados por Neil notando isso (x*w)%(h*w)==((x)%h)*w==(x)%h*w.

Solução 0 indexada.

Chas Brown
fonte
%h*w economiza 3 bytes acima *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]

Experimente online!

14 e 8 bytes jogados por @JayCe e @Mark.

A entrada ocorre [w, h], iporque R preenche a coluna de matrizes primeiro.

Cria a matriz e, em seguida, "triplica" a linha e a coluna. Em seguida, localize ina matriz original e encontre a vizinhança. Saída sem i.

ngm
fonte
1
Você pode salvar 14 bytes . Eu não sabia o que tinha um argumento arr.ind, aprendi alguma coisa hoje!
21418 JayCe
Você pode salvar 8 bytes substituindo-o seq()por #1:
Mark
3

PHP , 165 bytes

Isso é "baseado em 0". Deve haver uma solução melhor em PHP, mas este é um ponto de partida!

<?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;

Para executá-lo:

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

Exemplo:

php -n cell_neighbours.php 4 5 1

Ou Experimente online!

Night2
fonte
3

K (ngn / k) , 27 24 bytes

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

Experimente online!

{ }é uma função com argumentos x(as dimensões h w) e y(o índice i)

(!9)^4está 0 1 2 3 4 5 6 7 8sem o4

3\ codifica em ternário: (0 0;0 1;0 2;1 0;1 2;2 0;2 1;2 2)

1-subtrai de 1, fornecendo compensações vizinhas:(1 1;1 0;1 -1;0 1;0 -1;-1 1;-1 0;-1 -1)

x\yé a xcodificação base de y- as coordenadas de yna matriz

- subtrai cada deslocamento, dando-nos 8 pares de coordenadas vizinhas

x!''é mod xpara cada um - agrupa as coordenadas para permanecer na matriz

x/decodifica da base x- transforma pares de coordenadas em números inteiros únicos

ngn
fonte
Por curiosidade, sua variante de K tem um advérbio de "argumentos inversos", como o de J ~?
Conor O'Brien
1
@ ConorO'Brien Nenhum dos ks que eu conheço (Kx, Kona, OK e meu) tem isso, o que é lamentável para o golfe. Existem apenas 6 advérbios internos: / \ '/: \:': e nenhum mecanismo para os definidos pelo usuário.
ngn 19/07/19
É claro que eu poderia adicionar um advérbio de selfie, mas o golfe não é um fim em si para ngn / k, apenas um meio de acumular casos e experiências de teste.
ngn 19/07/19
Isso é justo. Obviamente, você pode vê-lo como uma falha potencial do idioma. Usei o PPCG para ajudar a desenvolver o Attache e percebi que o Attache não possuía algumas funções muito úteis que, de outra forma, eu não teria incluído. Não uso K, mas talvez haja outros casos de uso que justifiquem esse tipo de advérbio?
Conor O'Brien
@ ConorO'Brien Estou familiarizado com APL, que é como ~J, e estou convencido de sua utilidade, mas, veja bem, k é limitado a ASCII imprimível e (quase) sem dígrafos, portanto, um novo advérbio significaria o sacrifício de alguma outra primitiva útil, bem como mais incompatibilidade entre implementações. Não vejo o que posso fazer para colocar isso em questão.
ngn
2

MATL , 24 bytes

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

As entradas são h, w, i. A saída é um vetor de linha ou vetor de coluna com os números.

Entrada ie saída são baseadas em 1.

Experimente online! Ou verifique todos os casos de teste .

Explicação

*     % 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
fonte
2

Wolfram Language (Mathematica) , 74 bytes

Mod[i=#;w=#2;Mod[i+#2,w]+i~Floor~w+w#&@@@{-1,0,1}~Tuples~2~Delete~5,1##2]&

Experimente online!

Leva a entrada em reverso ( i, w, h), com base em 0.

Matriz 3x3 com a célula central, (60 bytes)

(Join@@(p=Partition)[Range[#2#]~p~#,a={1,1};3a,a,2a])[[#3]]&

Toma ( w, h, i), com base em 1.

Experimente online!

JungHwan Min
fonte
2

Lote, 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.

Indexado a 0. Economizou 23 bytes roubando o truque do módulo 3 de ChasBrown.

Neil
fonte
2

MATL, 24 bytes

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

Experimente no MATL Online

Toma entradas [w h]e i. 8 bytes disso foram descaradamente roubados, inspirados na resposta de Luis Mendos, embora a abordagem geral seja diferente.

sundar - Restabelecer Monica
fonte
1

Limpo , 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]]

Experimente online!

Trata icomo uma coordenada (0 <= p < h, 0 <= q < w)e gera os valores dos elementos adjacentes onde está o valor p'w + q'.

Furioso
fonte
1

Gelatina , 20 bytes

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

Um link diádico que aceita uma lista das dimensões à esquerda [h,w]e a célula como um número inteiro à direita i, o que gera uma lista da vizinhança.

Nota: a ordem é diferente da dos exemplos permitidos no OP

Experimente online!

Quão?

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
fonte
1

Anexo , 66 bytes

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

Experimente online!

Ainda preciso implementar Moorese NMoore, mas ainda tenho o Mooreque serve como uma função de iteração. Essencialmente, Integers@@__2cria uma matriz inteira de forma __2(os dois últimos argumentos) dos primeiros Prod[__2]inteiros. Isso nos dá a matriz de destino. Em seguida, Mooreitera a função {Push[a,_]}sobre cada vizinhança de Moore de tamanho 1(argumento implícito), com a opção de alternar cada elemento ( cycle->1). Isso adiciona cada vizinhança à matriz a. Então, Flat[a@_]aplaina o _membro th a, ou seja, o bairro de Moore centrado em torno _(o primeiro argumento). [0:3'5:8]obtém todos os membros, exceto o centro, dessa matriz achatada.

Esta solução, com uma atualização para o idioma, ficaria assim (49 bytes):

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

Kotlin , 88 bytes

Usa índices baseados em zero e gera uma lista de 8 elementos.

{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}}

Experimente online!

JohnWells
fonte