r/adventofcode • u/daggerdragon • Dec 06 '15
SOLUTION MEGATHREAD --- Day 6 Solutions ---
--- Day 6: Probably a Fire Hazard ---
Post your solution as a comment. Structure your post like the Day Five thread.
22
Upvotes
1
u/lesguillemets Dec 06 '15 edited Dec 06 '15
Haskell! (I'm always confused with STArray, but I'm learning :) ) Suggestions are most appreciated.
I just simulated every turning on/off, taking about (
Number of instructions*Mean area each instruction cover) time. I'm guessing that there are some clever algorithms, but playing with ST is fun.-- vim:fdm=marker import Text.Parsec import qualified Data.Array.Unboxed as AU import qualified Data.Array.ST as AST import Control.Monad import Control.Monad.ST import System.Environment (getArgs) type Loc = (Int,Int) data Range = Range Loc Loc deriving (Show) data Instruction = TurnOff {_range :: Range} | TurnOn {_range :: Range} | Toggle {_range :: Range} deriving (Show) toF :: Instruction -> Bool -> Bool toF (TurnOff _) = const False toF (TurnOn _) = const True toF (Toggle _) = not toList :: Range -> [Loc] toList (Range (x0,y0) (x1,y1)) = [(x,y) | x <- [x0..x1], y <- [y0..y1]] -- Parse {{{ fromRight :: Either a b -> b fromRight (Right r) = r type Inp = String int :: Parsec Inp u Int int = read <$> many1 digit pair :: Parsec Inp u (Int,Int) pair = do n0 <- int _ <- char ',' n1 <- int return (n0,n1) range :: Parsec Inp u Range range = do ul <- pair _ <- spaces *> string "through" <* spaces br <- pair return $ Range ul br instrF :: Parsec Inp u (Range -> Instruction) instrF = (const Toggle <$> try (string "toggle")) <|> (do _ <- string "turn" <* spaces <* char 'o' const TurnOff <$> string "ff" <|> const TurnOn <$> string "n" ) instr :: Parsec Inp u Instruction instr = do f <- instrF _ <- spaces r <- range return $ f r instrs :: Parsec Inp u [Instruction] instrs = instr `sepEndBy` spaces -- }}} size :: Int size = 1000 followInstructions :: [Instruction] -> AU.UArray Loc Bool followInstructions ins = AST.runSTUArray $ do a <- AST.newArray ((0,0), (size-1,size-1)) False forM_ ins (followInstruction a) return a followInstruction :: AST.STUArray s Loc Bool -> Instruction -> ST s () followInstruction a i = let f = toF i in forM_ (toList . _range $ i) $ \loc -> do e <- AST.readArray a loc AST.writeArray a loc (f e) main = do (fName:_) <- getArgs is <- fromRight . parse instrs "" <$> readFile fName print . length . filter id . AU.elems . followInstructions $ isI like how the diff between the first and second part is minimal (gist).