Очень распространенная потребность в классах алгоритмов и компьютерных науках в целом состоит в том, чтобы выполнять итерацию в четырех направлениях по сетке или матрице (например, в BFS или DFS). Это, кажется, часто приводит к большому количеству неуклюжего и многословного кода с большим количеством арифметики и сравнений внутри циклов. Я видел много разных подходов к этому, но я не могу избавиться от ощущения, что есть более краткий способ сделать это.
Задача состоит в том, чтобы написать чистую функцию, которая, учитывая ширину и высоту конечной плоскости, n, m
исходящей из точки (0,0)
, и координаты, (x,y)
которые могут представлять любую действительную точку в этой плоскости, возвращает итеративный объект всех точек в плоскости, которые направлены в 4 направлениях. рядом с (x,y)
.
Цель состоит в том, чтобы определить эту функцию как можно меньше байтов.
Некоторые примеры, которые помогут проиллюстрировать действительный ввод / вывод:
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)]
И вот пример (этот в Python) функции, которая удовлетворяет условиям:
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
В приведенном выше примере определена именованная функция, но также допустимы анонимные функции.
Входы n, m, x, y
представляют собой 32-разрядные целые числа без знака в следующих диапазонах:
n > 0
m > 0
0 <= x < m
0 <= y < n
Выходные данные должны принимать форму итерируемой (однако это зависит от выбранного вами языка) пары (x, y).
Дополнительные уточнения:
Комплексные числа (и другие представления / сериализации) в порядке, пока потребитель итерируемого может получить доступ x
и y
как целые числа, зная только их местоположение.
Индексы, не основанные на нулях, допустимы, но только в том случае, если выбранным языком является язык без нуля. Если язык использует сочетание систем нумерации, по умолчанию используется система нумерации структуры данных, наиболее часто используемая для представления матрицы. Если это все еще иностранные понятия в данном языке, любой начальный индекс приемлем.
(x,y)
он находится в прямоугольнике, верно?Ответы:
Python 2 , 66 байт
Попробуйте онлайн!
Перечисляет четырех соседей, затем использует нарезку списка для удаления тех, кто находится за пределами.
Python 2 , 71 байт
Попробуйте онлайн!
Вместо того, чтобы проверять, какие из четырех соседей являются внутренними, мы делаем это медленным способом проверки всех внутренних точек для тех, которые являются соседями, то есть имеют евклидово расстояние ровно 1 от
(x,y)
. Мы также используем классический трюк div-mod для итерации по сетке. , избавляя от необходимости писать два цикла вродеfor i in range(m)for j in range(n)
.Я пытался использовать сложную арифметику, чтобы написать условие расстояния, но оказалось, что писать дольше
abs((k/n-x)*1j+k%n-y)==1
.Python 2 , 70 байт
Попробуйте онлайн!
источник
октава , 90 байт
При этом используется геометрический подход: сначала мы создаем матрицу нулей желаемого размера и устанавливаем
1
в нужное место. Затем мы свернем с ядромкоторая производит новую матрицу того же размера с матрицами в 4-соседях исходной точки. Тогда мы
find()
индексы ненулевых элементов этой новой матрицы.Попробуйте онлайн!
свертка является ключом к успеху.
источник
Wolfram Language (Mathematica) , 42 байта
Попробуйте онлайн!
1-индексированный (что соответствует соглашению Mathematica об индексации). Принимает вход как
{x,y}, {m,n}
.для 0-индексированного ввода-вывода 45 байтов :
Попробуйте онлайн!
источник
JavaScript (ES6), 74 байта
Скучный подход.
Попробуйте онлайн!
JavaScript (Node.js) , 74 байта
Менее скучно, но так же долго. Принимает вход как
([h,w,x,y])
.Попробуйте онлайн!
JavaScript (V8) , 67 байт
Если бы были разрешены все стандартные методы вывода, мы могли бы просто напечатать действительные координаты с помощью:
Попробуйте онлайн!
источник
Желе ,
1312 байтДвоичный Ссылка принимая список из двух (0-индексированных) целых чисел на левой стороне ,
[row, column]
и два целых числа по правому[height, width]
, что дает список списков целых чисел,[[adjacent_row_1, adjacent_column_1], ...]
.Попробуйте онлайн!
Как?
источник
ḶṚƬ
наṬ€
.2ḶṚƬNƬẎ
возвращается[[0, 1], [1, 0], [0, -1], [-1, 0]]
, а2Ṭ€NƬẎ
возвращается[[1], [0, 1], [-1], [0, -1]]
и, поскольку синглтоны упакованы,+
только векторизуется с первым элементом⁸
для них, поэтому они действуют так, как будто их второй элемент0
(аддитивная идентичность). В результате может измениться только порядок вывода.Perl 6 ,
5649 байт-7 байт благодаря nwellnhof!
Попробуйте онлайн!
Удаляет элементы out of bounds, проверяя, находится ли он при делении на границы массива между 0 и 1. Принимает ввод и вывод через комплексные числа, где действительная часть - это
x
координата, а мнимая - этоy
. Вы можете извлечь их через.im
и.re
функции.источник
div
, похоже, не работает дляNum
s(*.reals>>.Int Zdiv@^b).none
или(*.reals Z/@^b)>>.Int.none
будет работать, но Int-Cast кажется слишком дорогим.J ,
302928 байтПопробуйте онлайн!
Как:
m
хn
арг в сетку комплексных чиселj./&i./
j./
1=|@-
#~&,
+.@
источник
C # (интерактивный компилятор Visual C #) , 91 байт
Попробуйте онлайн!
В качестве альтернативы:
Попробуйте онлайн!
источник
Древесный уголь , 29 байт
Попробуйте онлайн! Ссылка на подробную версию кода. Принимает входные данные в порядке x, y, ширина, высота. Объяснение:
Распечатайте
#
в предоставленной позиции.Зациклите данный прямоугольник.
Перейти к текущей позиции.
Если есть соседний,
#
сохраните позицию.Вывести обнаруженные позиции в конце цикла.
Скучный ответ:
Попробуйте онлайн! Ссылка на подробную версию кода. Работает, находя соседние позиции математически.
источник
Haskell, 62 байта
С помощью
Попробуйте онлайн!
Скучный подход: 81 байт
источник