Skip to content

Instantly share code, notes, and snippets.

@neonpixii
Last active March 6, 2018 06:06
Show Gist options
  • Save neonpixii/b43883486eec4862bc25c97542c434e8 to your computer and use it in GitHub Desktop.
Save neonpixii/b43883486eec4862bc25c97542c434e8 to your computer and use it in GitHub Desktop.
-- A cell is either on or off, and knows its
-- four cardinal neighbors directly.
-- state N W E S
data Cell = Edge | Cell Bool Cell Cell Cell Cell
-- nicely print life grids. takes a cell assumed
-- to be the top left cell of a grid & prints a
-- textual representation of the grid.
printLife :: Cell -> IO ()
printLife = let row Edge = putChar '\n'
row (Cell b _ _ e _)
| b = putChar 'o' *> row e
| otherwise = putChar ' ' *> row e
col Edge = putChar '\n'
col c = row c *> (col $ south c)
in col
state :: Cell -> Bool
state Edge = False
state (Cell b _ _ _ _) = b
north :: Cell -> Cell
north Edge = Edge
north (Cell _ n _ _ _) = n
west :: Cell -> Cell
west Edge = Edge
west (Cell _ _ w _ _) = w
east :: Cell -> Cell
east Edge = Edge
east (Cell _ _ _ e _) = e
south :: Cell -> Cell
south Edge = Edge
south (Cell _ _ _ _ s) = s
-- Returns number of living neighbors a cell has
moore :: Cell -> Int
moore Edge = 0
moore (Cell _ n w e s) = sum $ map f [east n,n,west n,w,e,east s,s,west s] where
f = fromEnum . state
-- Converts a 2d list of bools to a life grid & returns the top-left cell.
fromList :: [[Bool]] -> Cell
fromList xs = fromListCol Edge xs where
fromListCol _ [] = Edge
fromListCol _ ([]:rs) = fromListCol Edge rs
fromListCol n ((b:bs):rs) = c where
c = Cell b n Edge e s
s = fromListCol c rs
e = fromListRow c bs
fromListRow _ [] = Edge
fromListRow w (b:bs) = c where
c = Cell b (east $ north w) w e (east $ south w)
e = fromListRow c bs
-- takes a string (as a list of rows separated by newlines) and converts it
-- to a life grid, returning the top-left cell.. dead cells are represented
-- textually by ' ' or '\'', all other chars (except '\n') are considered to
-- be live cells.
fromString :: [Char] -> Cell
fromString cs = fromList $ map (map(\c->(c/=' ')&&(c/= '\''))) $ lines cs
-- the step function takes a cell that is assumed to be the top left cell in
-- a life grid and returns the top-left cell of the next generation of that
-- grid. in this source code, a variable marked with a ' denotes that it
-- represents a next-generation cell/value
step :: Cell -> Cell
step c = stepCol Edge c where
stepCol _ Edge = Edge
stepCol n' c@(Cell b n w e s) = c' where
c' = (Cell b' n' (south $ west n') e' s')
s' = stepCol c' s
e' = stepRow c' e
b' = (moore c == 3) || (moore c == 2 && b)
stepRow _ Edge = Edge
stepRow w' c@(Cell b n w e s) = c' where
c' = (Cell b' (east$north w') w' e' (east$south w'))
e' = stepRow c' e
b' = (moore c == 3) || (moore c == 2 && b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment