access the two neighbors of an element in a list
I'm trying to implement Wolfram’s elementary cellular automaton (rule 30) in haskell.
Result for ./wolfram 10
:
*
***
** *
** ****
** * *
** **** ***
** * * *
** **** ******
** * *** *
** **** ** * ***
To start, I generate this list : [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0]
where 0 is ' '
and 1 is '*'
.
Passing this list to the function genNextLine :: [Int] -> [Int]
will generate the next list.
For a given element, the next element is determined by its two neighbors (example : [0, 1, 1]
will generate a 1
).
I can iterate through the list element by element like this :
genNextLine :: [Int] -> [Int]
genNextLine (x : xs) = ...
But how can I iterate through the list by accessing elements x - 1
, x
, x + 1
?
Solution 1:
You can use pattern matching for prefixes of any length you want:
genNextLine :: [Int] -> [Int]
genNextLine (x1:x2:x3:xs) = (doSomethingWith x1 x2 x3):(getNextLine $ (x2:x3:xs))
genNextLine xs = xs
Btw, what about using zipWith3
?
genNextLine :: [Int] -> [Int]
genNextLine (x1:x2:xs) = zipWith3 doSomethingWith (x1:x2:xs) (x2:xs) xs