1
0
Fork 0
adventofcode/22b.hs

42 lines
1.6 KiB
Haskell
Raw Normal View History

2017-12-22 21:06:37 +00:00
{-# LANGUAGE BangPatterns, ScopedTypeVariables #-}
2017-12-22 08:37:21 +00:00
import Data.HashMap.Strict (HashMap, lookupDefault, insert, empty)
2017-12-22 21:06:37 +00:00
data Direction = North | East | South | West deriving (Bounded, Enum)
data Node = Weakened | Infected | Flagged | Clean deriving (Bounded, Enum, Eq)
type Grid = HashMap (Int, Int) Node
2017-12-22 08:37:21 +00:00
type State = (Grid, (Int, Int), Direction, Int)
2017-12-22 21:06:37 +00:00
(%) = mod; infixl 5 %
2017-12-22 08:37:21 +00:00
2017-12-22 21:06:37 +00:00
succn :: forall a. (Bounded a, Enum a) => Int -> a -> a
succn n = toEnum . (% 1 + fromEnum (maxBound :: a)) . (+ n) . fromEnum
2017-12-22 08:37:21 +00:00
incrementPosition :: Direction -> (Int, Int) -> (Int, Int)
incrementPosition dir (x, y) = case dir of
North -> (x, y - 1)
East -> (x + 1, y)
South -> (x, y + 1)
West -> (x - 1, y)
nextState :: State -> State
nextState (grid, pos, dir, count) =
2017-12-22 21:06:37 +00:00
let currNode = lookupDefault Clean pos grid
newDir = succn (fromEnum currNode) dir
newGrid = insert pos (succn 1 currNode) grid
2017-12-22 08:37:21 +00:00
newPos = incrementPosition newDir pos
2017-12-22 21:06:37 +00:00
!newCount = count + fromEnum (currNode == Weakened)
2017-12-22 08:37:21 +00:00
in (newGrid, newPos, newDir, newCount)
stricterate :: Int -> State -> Int
stricterate 0 (_, _, _, count) = count
stricterate n state = let !next = nextState state in stricterate (n-1) next
parseRow :: (Int, [(Int, Char)]) -> Grid -> Grid
2017-12-22 21:06:37 +00:00
parseRow (y, xs) grid = foldr (\(x, c) currGrid -> insert (x, y) (charToEnum c) currGrid) grid xs
where charToEnum c = case c of
'.' -> Clean
'#' -> Infected
2017-12-22 08:37:21 +00:00
main :: IO ()
main = do
2017-12-22 21:06:37 +00:00
grid <- foldr parseRow empty . zip [-12..12] . map (zip [-12..12]) . lines <$> readFile "22.txt"
2017-12-22 08:37:21 +00:00
print $ stricterate 10000000 (grid, (0, 0), North, 0)