diff --git a/2024/day01/day01.hs b/2024/day01/day01.hs new file mode 100644 index 0000000..74a112c --- /dev/null +++ b/2024/day01/day01.hs @@ -0,0 +1,18 @@ +import Data.List ( sort, group ) +import Data.Maybe ( fromMaybe ) +import Aoc ( aocMain ) + +parseFile :: [String] -> ([Int], [Int]) +parseFile lines = unzip [(a, b) | line <- lines, let [a, b] = map read $ words line] + +part1 :: ([Int], [Int]) -> Int +part1 (list1, list2) = sum $ zipWith (curry (abs . uncurry (-))) (sort list1) (sort list2) + +part2 :: ([Int], [Int]) -> Int +part2 (list1, list2) = sum $ map score list1 + where + score n = n * fromMaybe 0 (lookup n count) + count = map (\xs -> (head xs, length xs)) $ group $ sort list2 + +main :: IO () +main = aocMain parseFile part1 part2 diff --git a/2024/day02/day02.hs b/2024/day02/day02.hs new file mode 100644 index 0000000..ac0cf0d --- /dev/null +++ b/2024/day02/day02.hs @@ -0,0 +1,23 @@ +import Aoc ( aocMain ) + +parseFile :: [String] -> [[Int]] +parseFile = map (map read . words) + +part1 :: [[Int]] -> Int +part1 reports = + length $ filter isSafe $ map differences reports + where + differences xs = zipWith (-) xs (tail xs) + isGradual dx = 1 <= abs dx && abs dx <= 3 + isSafe dxs = all isGradual dxs && (all (<0) dxs || all (>0) dxs) + +part2 :: [[Int]] -> Int +part2 reports = + length $ filter isSafe $ map remove1 reports + where + remove n xs = let (front, back) = splitAt n xs in front ++ tail back + remove1 report = map (`remove` report) [0..length report-1] + isSafe = (>0) . part1 + +main :: IO () +main = aocMain parseFile part1 part2 \ No newline at end of file diff --git a/aoc.hs b/aoc.hs new file mode 100644 index 0000000..da16c4a --- /dev/null +++ b/aoc.hs @@ -0,0 +1,12 @@ +module Aoc where + +aocMain :: Show p => ([String] -> p) -> (p -> Int) -> (p -> Int) -> IO () +aocMain parseFile part1 part2 = do + contents <- readFile "input.txt" + let input = parseFile $ lines contents + -- print $ "Input: " ++ show input + print $ "Part 1: " ++ show (part1 input) + print $ "Part 2: " ++ show (part2 input) + +enumerate :: [a] -> [(Int, a)] +enumerate xs = zip [0..length xs] xs \ No newline at end of file