Вернуть индекс соседей в сетке 3х3

11

Хорошо, моя вторая попытка в коде гольф, давайте посмотрим, как это происходит.

Представьте, что у вас есть массив из 9 значений. Теперь представьте этот массив в сетке 3х3.

Вам нужно вернуть соседей, которые имеют номера в качестве индексов массива.

0 | 1 | 2

3 | 4 | 5

6 | 7 | 8

Правила:

  • Это код гольф, поэтому самый короткий ответ выигрывает.
  • Индекс массива pretend может начинаться с 0 или 1. (хотя во всех примерах используется 0)
  • Просто возвращение значений значений осуждается (как if 3: return 046)
  • Представление может быть просто процедурой / функцией / методом, но пример был бы хорош
  • Возвращаемое значение может быть в любом порядке (например, если input равен 0, это может быть 13 или 31)
  • если вы хотите, вывод может быть список чисел, например, [0,4,6]вместо046
  • диагонали не учитываются, как видно из примеров.

Примеры:

вход:

0

выход:

13

вход:

3

выход:

046

вход:

4

выход:

1357

hcorion
источник
4
Похоже, что этот вызов мог бы выиграть некоторое время в Песочнице . Вы можете опубликовать свой запрос там, чтобы другие могли просмотреть его и помочь вам с ним, прежде чем отправлять его на главную. По твоим примерам, я полагаю, ты не считаешь диагонали. Вы можете добавить это к самому вопросу. Вы также упоминаете требование для вывода индексов массива, которые являются соседями. Я думаю, что это может быть просто закодировано для сетки 3х3. Может быть, лучше вывести самих соседей?
Poke
7
Просто чтобы вы знали, нахмурившись на самом деле не то, что мы делаем здесь; Жесткое кодирование вывода либо разрешено, либо нет. Поскольку обычно довольно сложно определить, что именно считается жестким кодированием, я лично позволю это или предоставлю размер сетки в качестве дополнительного ввода.
Денис
1
Может ли вывод быть списком чисел, например, [0,4,6]вместо 046?
Лайкони
@Laikoni Да, немного поздно, потому что вы уже ответили.
hcorion
@ Денис Да, я не совсем знал, как это выразить. Мне нравится, как ответы на C и python сделали это, предоставив оба, но имея не жестко закодированный ответ в качестве окончательного. Я хотел поощрять алгоритмы, а не жесткое программирование, но я не был уверен, возможно ли это вообще (без чрезмерно длинных ответов), и я не хотел, чтобы у меня не было ответов на мой вопрос.
hcorion

Ответы:

2

Желе , 16 13 байт

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

Попробуйте онлайн!

Как это работает

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.
Деннис
источник
Правила гласят: «Индекс притворного массива может начинаться с 0 или 1». - вы можете сбросить декрет в конце.
Стинберг
@steenbergh Я полагаю, что тогда мне нужно будет также использовать ввод на основе 1, который стоит столько же байтов, сколько и экономит.
Денис
9

МАТЛ , 17 16 байт

9:qWIe1Y6Z+i)BPf

Массив основан на 1, то есть содержит числа из 1 до 9.

Попробуйте онлайн!Или проверьте все тестовые случаи .

объяснение

Рассмотрим ввод 2в качестве примера.

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]
Луис Мендо
источник
1
Wat? Как ты это придумал?
Роберт Фрейзер,
1
@RobertFraser Эти проблемы с поиском соседей всегда подсказывают мне подход свертки. Но свертка по своей сути добавляет ценности соседей, поэтому мне нужно было иметь возможность разделить их в конце - это степени двух степеней и двоичные части расширения
Луис Мендо,
5

Mathematica, 32 байта

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

Использует график вместо массива. GridGraph@{3,3}строит график 3x3 в форме сетки, показанный ниже, который по умолчанию Mathematica помечает номерами 1–9 для вершин. Затем ~AdjacencyList~#&говорит вам соседи вершины.

Граф сетки 3х3

Не дерево
источник
Должен любить тех встроенных ...
Нил
4

Mathematica, 40 байт

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

1-индексироваться. Просто ищет ответ. Кто-то может сделать лучше в Mathematica?

Грег Мартин
источник
3
Я удивлен, что для этого нет встроенной функции. Как и следовало ожидать, будет встроенная функция для поиска всех соседей элемента в двумерном массиве, но я не уверен, что ничего не знаю о Mathematica, кроме того факта, что в нем слишком много встроенных функций.
HyperNeutrino
2
Вы можете сохранить байт с помощью 0-индексации и 31[420,51,...,75][[#]]&.
Мартин Эндер
1
Можно использовать GridGraph@{3,3}~AdjacencyList~#&для 32 байтов, с 1-индексацией.
Не дерево
@ lanlock4 Отлично! Пожалуйста, дайте ответ, чтобы я мог проголосовать!
Грег Мартин
4

Октава, 42 40 39 байт

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

1 на основе индекса.

Проверьте все контрольные примеры.

Объяснение:

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.

Пример: n = 2

x =

   0   0   0
   1   0   0
   0   0   0

(В Octave данные хранятся по столбцам.)

d =

   1.00000   1.41421   2.23607
   0.00000   1.00000   2.00000
   1.00000   1.41421   2.23607

логический индекс, где расстояние равно 1:

d == 1

 1   0   0
 0   1   0
 1   0   0

find(d ==1)

 1
 3
 5
rahnema1
источник
3

Python 2, 71 байт

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

1-indexed
Попробуйте онлайн!


Получение результата из предварительно определенного списка результатов короче (46 байт):

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

0-indexed
Попробуйте онлайн!

овс
источник
2

Haskell , 74 71 68 байт

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]

Попробуйте онлайн! Использует 1-индексированную сетку. Пример использования: f 3возврат[2,6] .

Редактировать: Сохранено 3 6 байт, благодаря Орджану Йохансену!


Для 77 75 байтов следующая функция #работает для произвольного размера сетки 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]

Попробуйте онлайн! Для каждого nсписка [n-m,n-1,n+1,n+m]есть все четыре соседа. Для каждой записи xв этом списке мы проверяем -1<xи , x<m*mчтобы убедиться , xне выше или ниже сетки, mod n 3>0||n-1/=xчтобы обеспечить соблюдение границы левой сетки и mod(n+1)m>0||n+1/=xдля левой границы.

Laikoni
источник
1
Вы можете использовать [n-3,n-1..n+3]и gcd 3n>1.
Орджан Йохансен,
Ой, не обращайте внимания на эту gcdчасть. Так и должно было быть <3, а потом перерывы на n==0. Вы могли бы использовать этот трюк, если измените все на 1-индексированный.
Орджан Йохансен
Ох, и n/=2&&n/=5может быть заменен на mod x 3>0. (Или gcdверсия с переиндексацией, которая теперь может использоваться дважды.)
Орджан Йохансен,
2

Рубин , 51 48 45 байт

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

Попробуйте онлайн!

Создайте 2 массива с вертикальными и горизонтальными соседями, затем выберите один или несколько из них.

Рубиновый кодированный, 44 байта

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

... не стоит

гигабайт
источник
2

C 100 92 91 83 78 74 байта

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-индексироваться. Спасибо @Neil за сохранение 4 байта.

Попробуйте онлайн!

Версия в жестком коде, 56 байт

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

0 индексированные

Steadybox
источник
2
В первой версии вы не можете написать n>3&&p(n-3)и т. Д., Чтобы сохранить 4 байта? Во второй версии нельзя писать, l[]=чтобы сохранить байт?
Нил
@ Нейл Да, я могу. Благодаря!
Steadybox
Вы уверены, что ваш код в настоящее время правильный? Когда я пробую контрольные примеры, все три проваливаются ..: S Попробуй здесь. Не могли бы вы предоставить работающую TIO-ссылку, может я что-то не так делаю?
Кевин Круйссен,
1
Ссылка @KevinCruijssen TIO добавлена, и кажется, что я забыл отредактировать фактический код при последнем редактировании ... О, хорошо. Ваша ссылка тоже работает правильно, но обратите внимание, что мой ответ с 1 индексом, тогда как примеры тестовых примеров с 0 индексами.
Steadybox
@Steadybox Ах, ты действительно прав. Я пропустил 1-индексированную часть, моя плохая. Спасибо за добавление TIO. +1
Кевин Круйссен
1

Python 2, 51 байт

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

Основываясь на предыдущей версии моего ответа на Ruby , я нашел это интересным, потому что это был в основном тот же код, с использованием другого трюка и приводящий к тому же результату. Правильный ответ на этот вопрос помог мне немного больше ответить на вопрос о рубине.

По сути, у ruby ​​она короче, потому что индекс среза массива является включающим, +1для компенсации требуется python .

объяснение

Получите 2 массива (вертикальные и горизонтальные соседи), затем выберите один или оба на основе некоторых вычислений.

гигабайт
источник
1

Java 7, 63 байта (жестко закодировано)

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

0-indexed
(обратный порядок вывода, потому что 024и 046не являются действительными целыми числами.)
Все еще работает над не жестко закодированной версией, но я могу заверить вас, что она не будет короче ..

Попробуй это здесь.


82 байта

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

1-индексируется
на основе ответа @Steadybox 'C

Попробуй это здесь.

Кевин Круйссен
источник
0

JavaScript + lodash, 71 байт

f=a=>_.range(9).filter(b=>a>b?f(b).includes(a):[,1,,1][b-a]&&b%3|a%3<2)
Брайан Маккатон
источник
0

Пакет, 116 байт

@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

0 индексированные.

Нил
источник