diff options
Diffstat (limited to 'day14/day14.hs')
-rw-r--r-- | day14/day14.hs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/day14/day14.hs b/day14/day14.hs new file mode 100644 index 0000000..337fe68 --- /dev/null +++ b/day14/day14.hs @@ -0,0 +1,73 @@ +import Data.List +import Data.List.Split + +type Vec = (Int, Int) +type Robot = (Vec, Vec) + +size :: Vec +size = (101, 103) + +mul :: Int -> Vec -> Vec +mul s (x, y) = (s*x, s*y) +add :: Vec -> Vec -> Vec +add (x, y) (z, w) = (x+z, y+w) +clamp :: Vec -> Vec -> Vec +clamp m@(mx, my) v@(x, y) + | x < 0 = clamp m (x + mx, y) + | y < 0 = clamp m (x, y + my) + | x >= mx = clamp m (x - mx, y) + | y >= my = clamp m (x, y - my) + | otherwise = v + +consume1 :: String -> Robot +consume1 str = + ((atoi px, atoi py), (atoi vx, atoi vy)) + where + atoi = (read::String->Int) + ["p", px, py, "v", vx, vy] = splitOneOf "=, " str + +consume :: String -> [Robot] +consume file = + map consume1 $ lines file + +step :: [Robot] -> [Robot] +step robots = + map stepOne robots + where + stepOne (p, v) = (clamp size $ add p v, v) + +applyN :: Int -> (a -> a) -> a -> a +applyN n f = + foldr (.) id (replicate n f) + +count :: Vec -> Vec -> [Robot] -> Int +count tl br robots = + length $ filter (inside tl br) robots + where + inside (xs, ys) (xe, ye) ((x, y), _) = + x >= xs && x < xe && y >= ys && y < ye + +counts :: [Robot] -> (Int, Int, Int, Int) +counts robots = + (count (0, 0) (tx, ty) robots, + count ((tx + 1), 0) (mx, ty) robots, + count (0, (ty + 1)) (tx, my) robots, + count ((tx + 1), (ty + 1)) (mx, my) robots) + where + (mx, my) = size + tx = (mx - 1) `div` 2 + ty = (my - 1) `div` 2 + +safety :: (Int, Int, Int, Int) -> Int +safety (a, b, c, d) = + a * b * c * d + +part1 :: [Robot] -> Int +part1 robots = + safety $ counts $ applyN 100 step robots + +main = do + file <- readFile "day14.input" + let robots = consume file + putStrLn ("Part 1: " ++ (show $ part1 robots)) + --putStrLn ("Part 2: " ++ (show $ part2 robots)) |