Last active
March 6, 2018 06:06
-
-
Save neonpixii/b43883486eec4862bc25c97542c434e8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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