Well I can’t figure out how I could make it in haskell. For example, I have such matrix
[[1,2],[3,4]]
and I want to generate a list of lists with all possible neighbours of each element for this matrix.
Expected result is:
[[1,2],[1,3],[1,4],[2,1],[2,3],[2,4],[3,1],[3,2],[3,4],[4,1],[4,2],[4,3]]
I know how to make function which will create list of list with cords of neighbours of each cell:
pos how = [ (0+dx,0+dy) | dx <- [0..(how-2)], dy <- [0..how-1] ] :: [(Int,Int)]
neighbour (x,y) how = [ (x+dx,y+dy) | dy <- [-1..1], dx <- [-1..1],
x+dx >= 0, y+dy >= 0, x+dx<=how-2, y+dy <= how-1,
(x,y)/=(x+dx,y+dy) ] :: [(Int,Int)]
all_n how = [ p | x <- pos how, let p = neighbour x how ] :: [[(Int,Int)]]
but I can’t change it to work as I described.
Let me sketch a very different approach to the one you suggested. When talking about neighbors, I’ll say a d-neighbor of e is the element one step in direction d from element e. So, for example, in the matrix
[[1,2],[3,4]], the number2is a right-neighbor of number1. We’ll need to use some library code.We’ll start from the very simplest thing: let’s just find right-neighbors of a one-dimensional list.
We can find all the right-neighbors in a matrix by nondeterministically choosing a row of the matrix and finding all right-neighbors in that row.
We can take any function for finding neighbors and create the function for finding neighbors in the other direction by reversing the tuples. For example, left neighbors are the same as right neighbors, but with the tuple elements swapped, so:
What about down-neighbors? Actually, down-neighbors are just right-neighbors in the transposed matrix:
The next direction of interest are down-right-neighbors. This one is a little trickier; what we’re going to do is walk down two lists in parallel, but offset by one.
There’s one final direction, namely up-right-neighbors; these are down-right-neighbors if we flip the matrix upside down.
Finally, to form all neighbors, we can nondeterministically choose a neighboring direction, then find all neighbors in that direction.
The output isn’t in exactly the order you specified, but I imagine this may not matter so much.