Получить все возможные координаты соседей

Я представил трехмерную координату кортежем типа (Int, Int, Int)

Чтобы получить непосредственных соседей координаты, я сделал что-то вроде этого:

neighbours (x,y,z) =
    [(x',y',z') | x' <- [(x-1)..(x+1)], y' <- [(y-1)..(y+1)], z' <- [(z-1)..(z+1)], (x,y,z) /= (x',y',z')]

Теперь мне также нужно использовать 4D-координаты, я мог бы сделать что-то очень похожее, чтобы получить соседей с кортежем из 4 элементов, и это сработало бы. Но мне нужно будет продублировать все функции, которые я сделал для 3D-координат, на этот раз для 4D-координат.

Чтобы избежать этого, я подумал о том, чтобы в основном заменить кортежи списком Int, теперь для 3D-координаты это будет, например, [9, 3, 0] и 4D-координата [5, 1, 0, 1] и так далее.

Как я могу получить соседей с массивом Int? Я пытался использовать понимание списка, но мне не удалось найти решение.

PS: я новичок в Haskell и функциональном программировании.

Дублировать будет намного меньше, если вы реализуете это как neighbors (x,y,z) = delete (x,y,z) $ range ((x-1, y-1, z-1), (x+1, y+1, z+1)).

Daniel Wagner 21.12.2020 16:10
Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
1
219
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете продолжить рекурсивно и реализовать (N+1)-D соседей с точки зрения N-D соседей.

По сути, если у вас есть точка (N+1)-D [x1,...,xNplus1], она имеет форму x1 : xs, где xs — точка N-D. Итак, если вы уже знаете список соседей xs, вы можете превратить его в список соседей x1 : xs.

Вот простая попытка, которая должна почти сработать.

almostNeighbours :: [Int] -> [[Int]]
almostNeighbours []     = [[]]
almostNeighbours (x:xs) =
   [ x' : xs'
   | x' <- [x-1 .. x+1] , xs' <- almostNeighbours xs ]

Обратите внимание, что мы включаем саму точку в список соседей. В противном случае в рекурсивном случае не будет получено достаточного количества точек. (Я рекомендую убедить себя, что это действительно так.)

Если вам не нужна сама точка, вы всегда можете удалить ее позже с помощью дополнительной функции, не влияя на рекурсивное определение.

Наконец, обратите внимание, что приведенный выше код, вероятно, не будет таким же быстрым, как исходный, поскольку доступ к спискам медленнее, чем к кортежам.


Небольшая альтернатива: используя аппликативный стиль, мы можем немного сократить код.

almostNeighbours :: [Int] -> [[Int]]
almostNeighbours []     = pure []
almostNeighbours (x:xs) = (:) <$> [x-1 .. x+1] <*> almostNeighbours xs

Большое спасибо, это именно то, что я искал, и теперь, когда я это вижу, это имеет смысл. Это обязательно запомнят. Не могу отблагодарить вас достаточно!

visensis 20.12.2020 22:51

Другие вопросы по теме