From 5021a82bfd4e92ffdb99898b4a1871c079022c26 Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Fri, 5 Dec 2025 00:48:24 +0530 Subject: [PATCH] day 4: init Signed-off-by: Amneesh Singh --- aoc2025.cabal | 8 ++++++++ flake.nix | 2 +- src/Day04.hs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/Day04.hs diff --git a/aoc2025.cabal b/aoc2025.cabal index eb3f36d..fc5e794 100644 --- a/aoc2025.cabal +++ b/aoc2025.cabal @@ -41,3 +41,11 @@ executable day03 hs-source-dirs: src main-is: Day03.hs build-depends: libaoc + +executable day04 + import: common + hs-source-dirs: src + main-is: Day04.hs + build-depends: + , containers + , libaoc diff --git a/flake.nix b/flake.nix index cbdc53a..3fbca89 100644 --- a/flake.nix +++ b/flake.nix @@ -45,7 +45,7 @@ name = n: "day${(if n < 10 then "0" else "") + toString n}"; in with pkgs.lib; - genAttrs (map name (range 1 3)) (n: { + genAttrs (map name (range 1 4)) (n: { type = "app"; program = "${self'.packages.aoc2025}/bin/${n}"; }); diff --git a/src/Day04.hs b/src/Day04.hs new file mode 100644 index 0000000..950e8c5 --- /dev/null +++ b/src/Day04.hs @@ -0,0 +1,51 @@ +import qualified Data.Set as S (Set, difference, empty, foldr', fromList, insert, member, null, size) + +type Roll = (Int, Int) + +type Rolls = S.Set Roll + +accessible :: Rolls -> Rolls +accessible rolls = + S.foldr' + (\p acc -> if reachable p <= 4 then S.insert p acc else acc) + S.empty + rolls + where + reachable (x, y) = + length + [ () + | dx <- [-1 .. 1], + dy <- [-1 .. 1], + let p' = (x + dx, y + dy), + S.member p' rolls + ] + +part1 :: Rolls -> Int +part1 = S.size . accessible + +part2 :: Rolls -> Int +part2 = go 0 + where + go :: Int -> Rolls -> Int + go n rolls = + let accRolls = accessible rolls + in if S.null accRolls + then n + else + let remaining = rolls `S.difference` accRolls + in go (n + S.size accRolls) remaining + +main :: IO () +main = + do + raw <- readFile "./inputs/day4.in" + let rolls = + S.fromList + [ (x, y) + | (y, line) <- zip [0 ..] (lines raw), + (x, ch) <- zip [0 ..] line, + ch == '@' + ] + + putStr "Part 1: " >> print (part1 rolls) + putStr "Part 2: " >> print (part2 rolls)