diff options
author | Nat Lasseter <user@4574.co.uk> | 2024-12-08 17:01:16 +0000 |
---|---|---|
committer | Nat Lasseter <user@4574.co.uk> | 2024-12-08 17:01:16 +0000 |
commit | b30ffe15b486fc82665b52c8b8bdcfc58c2bf0d4 (patch) | |
tree | 6e12d7981f60134e1fd02337f66ee4e32f02de1c /day08/day08.hs | |
parent | 1d41bdb5e3807c366c6a38c6233377a2721b9a1f (diff) |
[Day 08] Done
Diffstat (limited to 'day08/day08.hs')
-rw-r--r-- | day08/day08.hs | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/day08/day08.hs b/day08/day08.hs new file mode 100644 index 0000000..728dd71 --- /dev/null +++ b/day08/day08.hs @@ -0,0 +1,83 @@ +import Data.List + +type Vec = (Int, Int) +type Ant = (Int, Int, Char) +type Map = (Vec, [Ant]) + +consume2 :: [Ant] -> Int -> Int -> [Char] -> [Ant] +consume2 acc _ _ [] = acc +consume2 acc r c ('.':t) = consume2 acc r (c+1) t +consume2 acc r c (h:t) = consume2 ((r, c, h):acc) r (c+1) t + +consume1 :: [Ant] -> Int -> [[Char]] -> [Ant] +consume1 acc _ [] = acc +consume1 acc r (h:t) = consume1 (acc ++ (consume2 [] r 0 h)) (r+1) t + +consume :: [Char] -> Map +consume file = + ((length grid, length $ head grid), consume1 [] 0 grid) + where grid = lines file + +neg :: Vec -> Vec +neg (r, c) = (-r, -c) +add :: Vec -> Vec -> Vec +add (fr, fc) (dr, dc) = (fr + dr, fc + dc) +scale :: Int -> Vec -> Vec +scale m (r, c) = (r * m, c * m) +path :: (Vec, Vec) -> Vec +path (f, t) = add t $ neg f + +inside :: Vec -> Vec -> Bool +inside (mr, mc) (r, c) = + r >= 0 && r < mr && c >= 0 && c < mc + +simplify :: Vec -> Vec +simplify (r, c) = + (r `div` d, c `div` d) + where d = gcd r c + +antiNodes :: Map -> Char -> [Vec] +antiNodes (size, ants) freq = + filter (inside size) $ map (\p@(f, _) -> add f $ scale 2 $ path p) pairs + where + fants = filter (\(_, _, f) -> f == freq) ants + coos = map (\(r, c, _) -> (r, c)) fants + pairs = [(a1, a2) | a1 <- coos, a2 <- coos, a1 /= a2] + +antiNodes22 :: [Vec] -> Vec -> Vec -> Vec -> [Vec] +antiNodes22 acc size from del + | inside size nxt = antiNodes22 (nxt:acc) size nxt del + | otherwise = acc + where nxt = add from del + +antiNodes21 :: Vec -> (Vec, Vec) -> [Vec] +antiNodes21 s p@(f, t) = + antiNodes22 [] s f d ++ + [f] ++ + antiNodes22 [] s f (neg d) + where + d = simplify $ path p + +antiNodes2 :: Map -> Char -> [Vec] +antiNodes2 (size, ants) freq = + nub $ concat $ map (antiNodes21 size) pairs + where + fants = filter (\(_, _, f) -> f == freq) ants + coos = map (\(r, c, _) -> (r, c)) fants + pairs = [(a1, a2) | a1 <- coos, a2 <- coos, a1 /= a2] + +part1 mp@(_, ants) = + length $ nub $ concat $ map (antiNodes mp) freqs + where + freqs = nub $ map (\(_, _, f) -> f) ants + +part2 mp@(_, ants) = + length $ nub $ concat $ map (antiNodes2 mp) freqs + where + freqs = nub $ map (\(_, _, f) -> f) ants + +main = do + file <- readFile "day08.input" + let mp = consume file + putStrLn ("Part 1: " ++ (show $ part1 mp)) + putStrLn ("Part 2: " ++ (show $ part2 mp)) |