diff --git a/2015/day06/day06.hs b/2015/day06/day06.hs new file mode 100644 index 0000000..468a14e --- /dev/null +++ b/2015/day06/day06.hs @@ -0,0 +1,38 @@ +import Aoc +import Data.List.Split ( splitOn ) + +parseFile :: [String] -> [(String, (Int, Int), (Int, Int))] +parseFile = map (\line -> + let line' = words line in + let (command, [pos1, "through", pos2]) = splitAt (length line' - 3) line' in + (unwords command, pos pos1, pos pos2)) + where pos = pair . map read . splitOn "," + +doCommands :: (a -> String -> a) -> a -> [(String, (Int, Int), (Int, Int))] -> (Int, Int) -> a +doCommands doCommand start commands pos = foldl (doCommand' pos) start commands + where + within (x0, y0) (x1, y1) (x, y) = x0 <= x && x <= x1 && y0 <= y && y <= y1 + doCommand' pos state (command, pos1, pos2) = if within pos1 pos2 pos then doCommand state command else state + + +part1 :: [(String, (Int, Int), (Int, Int))] -> Int +part1 commands = length $ filter isOn [(x, y) | x <- [0..999], y <- [0..999]] + where + doCommand state "turn off" = False + doCommand state "turn on" = True + doCommand state "toggle" = not state + + isOn = doCommands doCommand False commands + + +part2 :: [(String, (Int, Int), (Int, Int))] -> Int +part2 commands = sum [brightness (x, y) | x <- [0 .. 999], y <- [0 .. 999]] + where + doCommand state "turn off" = max 0 (state - 1) + doCommand state "turn on" = state + 1 + doCommand state "toggle" = state + 2 + + brightness = doCommands doCommand 0 commands + +main :: IO () +main = aocMain parseFile part1 part2 \ No newline at end of file