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