this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

1module Lib 2 ( parseGrid 3 , initCarrier 4 , doBurst 5 , getCount 6 ) where 7 8import qualified Data.Map.Strict as M 9import Data.List (foldl') 10 11data Dir = N | E | S | W deriving (Show) 12 13data Carrier = Carrier (Int, Int) Dir Int deriving (Show) 14 15type Grid = M.Map (Int, Int) Int 16 17parseGrid :: [String] -> Grid 18parseGrid strs = 19 let coords = [ (x, y) | x <- [0..length strs - 1], y <- [0..length strs - 1] ] 20 in foldl' (\m c@(x, y) -> let v = if strs!!y!!x == '#' then 1 else 0 21 in M.insert c v m 22 ) M.empty coords 23 24startingPos :: Grid -> (Int, Int) 25startingPos grid = case M.lookupMax grid of 26 Just ((x, y), _) -> ((div x 2), (div y 2)) 27 Nothing -> (0, 0) 28 29initCarrier :: Grid -> Carrier 30initCarrier g = Carrier (startingPos g) N 0 31 32doBurst :: (Grid, Carrier) -> (Grid, Carrier) 33doBurst (grid, c@(Carrier pos _ _)) = 34 case M.lookup pos grid of 35 Just v -> case v of 36 0 -> (M.adjust (\_ -> updateNodeState v) pos grid, move . turnLeft $ c) 37 1 -> (M.adjust (\_ -> updateNodeState v) pos grid, move . turnRight $ c) 38 2 -> (M.adjust (\_ -> updateNodeState v) pos grid, increaseCount . move $ c) 39 _ -> (M.adjust (\_ -> updateNodeState v) pos grid, move . turnRight . turnRight $ c) 40 Nothing -> (M.insert pos (updateNodeState 0) grid, move . turnLeft $ c) 41 42increaseCount :: Carrier -> Carrier 43increaseCount (Carrier pos dir count) = Carrier pos dir (count + 1) 44 45updateNodeState :: Int -> Int 46updateNodeState 0 = 2 -- Cleaned -> Weakened 47updateNodeState 2 = 1 -- Weakened -> Infected 48updateNodeState 1 = 3 -- Infected -> Flagged 49updateNodeState 3 = 0 -- Flagged -> Cleaned 50updateNodeState _ = 0 -- ??? -> Cleaned 51 52getCount :: Carrier -> Int 53getCount (Carrier _ _ c) = c 54 55move :: Carrier -> Carrier 56move (Carrier (x, y) N count) = Carrier (x, y - 1) N count 57move (Carrier (x, y) W count) = Carrier (x + 1, y) W count 58move (Carrier (x, y) S count) = Carrier (x, y + 1) S count 59move (Carrier (x, y) E count) = Carrier (x - 1, y) E count 60 61turnRight :: Carrier -> Carrier 62turnRight (Carrier pos N count) = Carrier pos W count 63turnRight (Carrier pos W count) = Carrier pos S count 64turnRight (Carrier pos S count) = Carrier pos E count 65turnRight (Carrier pos E count) = Carrier pos N count 66 67turnLeft :: Carrier -> Carrier 68turnLeft (Carrier pos N count) = Carrier pos E count 69turnLeft (Carrier pos E count) = Carrier pos S count 70turnLeft (Carrier pos S count) = Carrier pos W count 71turnLeft (Carrier pos W count) = Carrier pos N count 72 73 74 -- if current infected, turn right, otherwise turn left 75 -- if infected