Retornar índice de vizinhos em uma grade 3x3

11

Tudo bem, minha segunda tentativa de um código de golfe, vamos ver como isso acontece.

Finja que você tem uma matriz de 9 valores. Agora imagine essa matriz em uma grade 3x3.

Você precisa retornar aos vizinhos esse número como índices da matriz.

0 1 | 2

3 4 5

6 7 8

Regras:

  • É código de golfe, portanto, a resposta mais curta vence.
  • O índice da matriz fingida pode começar em 0 ou 1. (embora todos os exemplos usem 0)
  • Apenas retornar valores é desaprovado (como if 3: return 046)
  • A submissão pode ser apenas um procedimento / função / método, mas um exemplo seria bom
  • O valor retornado pode estar em qualquer ordem (como se a entrada fosse 0, poderia ser 13 ou 31)
  • se desejar, a saída pode ser uma lista de números, por exemplo, em [0,4,6]vez de046
  • diagonais não contam, como visto nos exemplos.

Exemplos:

entrada:

0 0

resultado:

13

entrada:

3

resultado:

046

entrada:

4

resultado:

1357

hcorion
fonte
4
Parece que esse desafio pode se beneficiar de algum tempo na Sandbox . Você pode postar seu desafio lá para que outros possam revisá-lo e ajudá-lo antes de publicá-lo no main. Pelos seus exemplos, acho que você não está contando diagonais. Você pode adicionar isso à própria pergunta. Você também mencionou o requisito para gerar os índices da matriz vizinhos. Eu acho que isso poderia ser codificado para uma grade 3x3. Seria talvez melhor produzir os próprios vizinhos?
Puxão
7
Só para você saber, desaprovado não é realmente algo que fazemos aqui; codificar a saída é permitido ou não. Como geralmente é muito difícil definir o que exatamente conta como codificação codificada, eu pessoalmente permitiria ou daria o tamanho da grade como uma entrada adicional.
Dennis
1
A saída pode ser uma lista de números, por exemplo, em [0,4,6]vez de 046?
Laikoni 26/03
@Laikoni Sim, um pouco tarde demais, porque você já respondeu.
Hcorion
@ Dennis Sim, eu não tinha muita certeza de como colocá-lo. Eu gosto de como as respostas C e python fizeram isso, fornecendo as duas, mas tendo a resposta não codificada como final. Queria encorajar algoritmos em vez de codificar, mas não tinha certeza se era possível (sem respostas muito longas) e não queria ter respostas para minha pergunta.
Hcorion

Respostas:

2

Geléia , 16 13 bytes

9Ḷ,d3ạ/S€=1T’

Experimente online!

Como funciona

9Ḷ,d3ạ/S€=1T’  Main link. Argument: n (0, ..., 8)

9              Set the return value to 9.
 Ḷ             Unlength; yield [0, ..., 8].
  ,            Pair; yield [[0, ..., 8], n].
   d3          Divmod 3; yield [[[0, 0], ..., [2, 2]], [n:3, n%3]]].
     ạ/        Reduce by absolute difference, yielding
               [[|0 - n:3|, |0 - n%3|], ..., [[|2 - n:3|, |2 - n%3|]].
       S€      Sum each, yielding
               [|0 - n:3| + |0 - n%3|, ..., [|2 - n:3| + |2 - n%3|].
         =1    Compare the sums with 1.
           T   Truth; yield all 1-based indices of 1.
            ’  Decrement to yield all 0-based indices of 1.
Dennis
fonte
As regras declaram: "O índice da matriz fingida pode começar em 0 ou 1." - você pode largar o decremento no final.
22417
@steenbergh Suponho que teria de receber uma entrada baseada em 1 também, o que custa tantos bytes quanto economiza.
Dennis
9

MATL , 17 16 bytes

9:qWIe1Y6Z+i)BPf

A matriz é baseada em 1, ou seja, contém números de 1até 9.

Experimente online! Ou verifique todos os casos de teste .

Explicação

Considere a entrada 2como um exemplo.

9:q  % Push [0 1 2 ... 8]
     % STACK: [0 1 2 ... 8]
W    % Rise to 2, element-wise
     % STACK: [1 2 4 ... 256]
Ie   % Reshape as 3-row matrix (column-major order)
     % STACK: [1   8  64;
               2  16 128;
               4  32 256]
1Y6  % Push [0 1 0; 1 0 1; 0 1 0]
     % STACK: [1   8  64;
               2  16 128;
               4  32 256],
              [0   1   0;
               1   0   1;
               0   1   0]
Z+   % Convolution, maintaining size
     % STACK: [10  81 136;
               21 170 336;
               34 276 160]
i    % Take input, n
     % STACK: [10  81 136;
               21 170 336;
               34 276 160],
               2
 )   % Get n-th entry (1-based; column-major order)
     % STACK: 21
B    % Convert to binary
     % STACK: [1 0 1 0 1]
P    % Flip
     % STACK: [1 0 1 0 1]
f    % Find: gives indices of nonzeros. Implicitly display
     % STACK: [1 3 5]
Luis Mendo
fonte
1
Wat? Como você chegou a isso?
31417 Robert
1
@RobertFraser Esses desafios em encontrar vizinhos sempre me sugerem uma abordagem de convolução. Mas convolução inerentemente adiciona os vizinhos valores, então eu precisava para ser capaz de separá-los no final --- que é os poderes-de-dois e peças de expansão binários
Luis Mendo
5

Mathematica, 32 bytes

GridGraph@{3,3}~AdjacencyList~#&

Usa um gráfico em vez de uma matriz. GridGraph@{3,3}constrói um gráfico em forma de grade 3x3, mostrado abaixo, que o Mathematica rotula com os números de 1 a 9 para os vértices por padrão. Em seguida, ~AdjacencyList~#&informa os vizinhos de um vértice.

O gráfico de grade 3x3

Não é uma árvore
fonte
Conseguiu amar aqueles builtins ...
Neil
4

Mathematica, 40 bytes

{24,135,26,157,2468,359,48,579,68}[[#]]&

1 indexado. Apenas procura a resposta. Alguém pode fazer melhor no Mathematica?

Greg Martin
fonte
3
Estou surpreso que não há um builtin para isso. Como eu esperaria que houvesse um builtin para encontrar todos os vizinhos de um elemento em uma matriz 2D, mas não tenho certeza, não sei nada sobre o Mathematica além do fato de que ele tem muitos buildins.
HyperNeutrino
2
Você pode salvar um byte usando a indexação 0 e 31[420,51,...,75][[#]]&.
Martin Ender
1
Você pode usar GridGraph@{3,3}~AdjacencyList~#&para 32 bytes, com 1 indexação.
Não é uma árvore
@ lanlock4 Awesome! Faça uma resposta para que eu possa votar novamente!
Greg Martin
4

Oitava, 42 40 39 bytes

@(n,x=~e(3),y=x(n)=1)find(bwdist(x)==1)

Índice baseado em 1.

Verifique todos os casos de teste.

Explicação:

x=~e(3);         % create a 3*3 matrix of zeros
x(n)=1;          % set the element with index n to 1
d=bwdist(x);     % compute the distance transform of the matrix
find(d == 1)     % find where the distance is 1.

Exemplo: n = 2

x =

   0   0   0
   1   0   0
   0   0   0

(No Octave, os dados são armazenados em colunas.)

d =

   1.00000   1.41421   2.23607
   0.00000   1.00000   2.00000
   1.00000   1.41421   2.23607

índice lógico em que a distância é 1:

d == 1

 1   0   0
 0   1   0
 1   0   0

find(d ==1)

 1
 3
 5
rahnema1
fonte
3

Python 2, 71 bytes

lambda n:filter(abs,[(n-3)*(n>3),(n+3)*(n<7),~-n*(n%3!=1),-~n*(n%3>0)])

1-indexado
Experimente online!


Obter o resultado de uma lista predefinida de resultados é mais curto (46 bytes):

[13,204,15,406,1357,248,37,468,57].__getitem__

0-indexado
Experimente online!

ovs
fonte
2

Haskell , 74 71 68 bytes

f n=[x|x<-[n-3,n-1..n+3],0<x,x<10,gcd 3x<2||n-1/=x,gcd 3n<2||n+1/=x]

Experimente online! Usa uma grade indexada 1. Exemplo de uso: f 3retorna [2,6].

Edit: Salvo 3 6 bytes graças a Ørjan Johansen!


Para 77 75 bytes, a seguinte função #funciona para um tamanho de grade arbitrário m:

n#m=[x|x<-[n-m,n-1,n+1,n+m],0<x,x<=m*m,gcd x m<m||n-1/=x,gcd n m<m||n+1/=x]

Experimente online! Para cada uma, na lista [n-m,n-1,n+1,n+m]contém todos os quatro vizinhos. Para cada entrada xnesta lista, verificamos -1<xe x<m*mgarantimos que xnão esteja acima ou abaixo da grade, mod n 3>0||n-1/=xpara aplicar a borda esquerda da grade e mod(n+1)m>0||n+1/=xa borda esquerda.

Laikoni
fonte
1
Você pode usar [n-3,n-1..n+3]e gcd 3n>1.
Ørjan Johansen
Opa, deixa pra lá essa gcdparte. Deveria ter sido <3, e então quebra n==0. Você poderá usar esse truque se alterar tudo para 1-indexed.
Ørjan Johansen
Ah, e o n/=2&&n/=5pode ser substituído por mod x 3>0. (Ou a gcdversão com reindexing, que agora pode ser usada duas vezes.) #
Ørjan Johansen
2

Ruby , 51 48 45 bytes

->a{[a+3,a-3][a/6..a/3]+[a+1,a-1][a%-3..a%3]}

Experimente online!

Crie 2 matrizes, com vizinhos verticais e horizontais, depois selecione uma ou mais delas.

Ruby codificado, 44 ​​bytes

->a{%w(13 024 15 046 1357 248 37 468 57)[a]}

... Não vale a pena.

GB
fonte
2

C, 100 92 91 83 78 74 bytes

p(n){putchar(n+48);}f(n){n>3&&p(n-3);n<7&&p(n+3);n%3&&p(n+1);--n%3&&p(n);}

1 indexado. Obrigado a @Neil por salvar 4 bytes.

Experimente online!

Versão codificada, 56 bytes

l[]={13,204,15,406,1357,248,37,468,57};
#define L(n)l[n]

Indexado a 0

Steadybox
fonte
2
Na primeira versão, você não pode escrever n>3&&p(n-3)etc. para salvar 4 bytes? Na segunda versão, você não pode escrever l[]=para salvar um byte?
27417 Neil
@ Neil Sim, eu posso. Obrigado!
Steadybox
Tem certeza de que seu código está correto no momento? Quando tento os casos de teste, ele falha nos três ..: S Experimente aqui. Você poderia fornecer um link TIO funcional, talvez eu esteja fazendo algo errado?
Kevin Cruijssen 27/03
1
@KevinCruijssen Link TIO adicionado, e parece que eu esqueci de editar o código real na última edição ... Ah, bem. Seu link também está funcionando corretamente, mas observe que minha resposta é indexada 1, enquanto os casos de teste de exemplo são indexados 0.
Steadybox
@Steadybox Ah, você está realmente certo. Eu perdi a parte 1 indexada, minha má. Obrigado por adicionar o TIO. 1
Kevin Cruijssen 27/03
1

Python 2, 51 bytes

lambda x:[x+3,x-3][x/6:x/3+1]+[x+1,x-1][x%-3:x%3+1]

Com base em uma versão anterior da minha resposta Ruby , achei interessante porque era basicamente o mesmo código, usando um truque diferente e produz o mesmo resultado. Conseguir este direito me ajudou a responder um pouco mais à resposta do rubi.

Basicamente, o ruby ​​é mais curto porque o índice de fatia da matriz é inclusivo, o python precisa de um +1para compensar.

Explicação

Obtenha as 2 matrizes (vizinhos verticais e horizontais) e selecione uma ou ambas com base em alguns cálculos.

GB
fonte
1

Java 7, 63 bytes (codificado)

int c(int i){return new int[]{31,420,51,640,7531,842,73,864,75}[i];}

0-indexados
(saída ordem inversa porque 024e 046não são inteiros válidos.)
Ainda trabalhando em uma versão não-codificado, mas posso garantir-vos que não será mais curto ..

Experimente aqui.


82 bytes

String c(int n){return""+(n>3?n-3:"")+(n<7?n+3:"")+(n%3>0?n+1:"")+(--n%3>0?n:"");}

1 indexado com
base na resposta C do @Steadybox '

Experimente aqui.

Kevin Cruijssen
fonte
0

JavaScript + lodash, 71 bytes

f=a=>_.range(9).filter(b=>a>b?f(b).includes(a):[,1,,1][b-a]&&b%3|a%3<2)
Brian McCutchon
fonte
0

Lote, 116 bytes

@set c=cmd/cset/a%1
@set/ar=%1%%3
@if %1 gtr 2 %c%-3
@if %r% gtr 0 %c%-1
@if %r% lss 2 %c%+1
@if %1 lss 6 %c%+3

Indexado a 0.

Neil
fonte