@@ -49,3 +49,9 @@ executable day04
|
||||
build-depends:
|
||||
, containers
|
||||
, libaoc
|
||||
|
||||
executable day05
|
||||
import: common
|
||||
hs-source-dirs: src
|
||||
main-is: Day05.hs
|
||||
build-depends: libaoc
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
name = n: "day${(if n < 10 then "0" else "") + toString n}";
|
||||
in
|
||||
with pkgs.lib;
|
||||
genAttrs (map name (range 1 4)) (n: {
|
||||
genAttrs (map name (range 1 5)) (n: {
|
||||
type = "app";
|
||||
program = "${self'.packages.aoc2025}/bin/${n}";
|
||||
});
|
||||
|
||||
41
src/Day05.hs
Normal file
41
src/Day05.hs
Normal file
@@ -0,0 +1,41 @@
|
||||
import qualified AoC as A (extract)
|
||||
import Data.List (sort)
|
||||
import Text.Parsec (char, digit, many1, newline, parse, sepEndBy, sepEndBy1)
|
||||
import Text.Parsec.String (Parser)
|
||||
|
||||
type Id = Int
|
||||
|
||||
type Range = (Id, Id)
|
||||
|
||||
parseInput :: Parser ([Range], [Id])
|
||||
parseInput = (,) <$> sepEndBy1 parseRange newline <* newline <*> sepEndBy parseId newline
|
||||
where
|
||||
parseRange :: Parser Range
|
||||
parseRange = (,) <$> parseId <* char '-' <*> parseId
|
||||
|
||||
parseId :: Parser Id
|
||||
parseId = read <$> many1 digit
|
||||
|
||||
part1 :: [Range] -> [Id] -> Int
|
||||
part1 ranges = sum . map (fromEnum . fresh)
|
||||
where
|
||||
fresh :: Id -> Bool
|
||||
fresh id = or [id >= a && id <= b | (a, b) <- ranges]
|
||||
|
||||
part2 :: [Range] -> Int
|
||||
part2 =
|
||||
sum . map (\(l, r) -> r - l + 1) . foldr step [] . sort
|
||||
where
|
||||
step :: Range -> [Range] -> [Range]
|
||||
step lst [] = [lst]
|
||||
step (l1, r1) acc@((l2, r2) : xs)
|
||||
| r1 < l2 = (l1, r1) : acc
|
||||
| otherwise = (l1, max r1 r2) : xs
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
do
|
||||
raw <- readFile "./inputs/day5.in"
|
||||
let (ranges, ids) = A.extract $ parse parseInput "" raw
|
||||
putStr "Part 1: " >> print (part1 ranges ids)
|
||||
putStr "Part 2: " >> print (part2 ranges)
|
||||
Reference in New Issue
Block a user