diff --git a/aoc2024.cabal b/aoc2024.cabal index cc9d80d..05b7750 100644 --- a/aoc2024.cabal +++ b/aoc2024.cabal @@ -14,8 +14,10 @@ common warnings library import: warnings - exposed-modules: Day1, Day2 - build-depends: base ^>=4.18.0.0 + exposed-modules: Day1, Day2, Day3 + build-depends: base ^>=4.18.0.0 + , regex + , array hs-source-dirs: src default-language: GHC2021 diff --git a/run/Main.hs b/run/Main.hs index 3e10125..15ccfac 100644 --- a/run/Main.hs +++ b/run/Main.hs @@ -1,10 +1,13 @@ module Main where import qualified Day1 as D1 import qualified Day2 as D2 +import qualified Day3 as D3 solutions :: [(String -> String, String -> String)] -solutions = [(D1.part1, D1.part2), - (D2.part1, D2.part2)] +solutions = [ (D1.part1, D1.part2) + , (D2.part1, D2.part2) + , (D3.part1, D3.part2) + ] run :: Int -> Int -> IO () diff --git a/src/Day3.hs b/src/Day3.hs new file mode 100644 index 0000000..678745c --- /dev/null +++ b/src/Day3.hs @@ -0,0 +1,34 @@ +{-# LANGUAGE QuasiQuotes #-} +module Day3 (part1, part2) where + +import Text.RE.TDFA.String +import Text.RE.Replace +import Data.Array + +part1 :: String -> String +part1 = show + . sum + . map (\x -> + (read $ capturedText $ x ! 1 :: Integer) + * (read $ capturedText $ x ! 2 :: Integer) + ) + . map matchArray + . allMatches + . (*=~ [re|mul\(([0-9]{1,3}),([0-9]{1,3})\)|]) + + + +part2 :: String -> String +part2 = show + . snd + . foldl (\(on, acc) new -> + case head new of + "do()" -> (True, acc) + "don't()" -> (False, acc) + _ -> if not on then (on, acc) else + (on, acc + (read $ new !! 2 :: Integer) * (read $ new !! 3 :: Integer)) + ) (True, 0) + . map (map capturedText . elems) + . map matchArray + . allMatches + . (*=~ [re|(do\(\)|don't\(\)|mul\(([0-9]{1,3}),([0-9]{1,3})\))|]) diff --git a/test/1.testcase b/test/1 similarity index 100% rename from test/1.testcase rename to test/1 diff --git a/test/2.testcase b/test/2 similarity index 100% rename from test/2.testcase rename to test/2 diff --git a/test/3.1 b/test/3.1 new file mode 100644 index 0000000..f274bda --- /dev/null +++ b/test/3.1 @@ -0,0 +1 @@ +xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5)) diff --git a/test/3.2 b/test/3.2 new file mode 100644 index 0000000..30032cb --- /dev/null +++ b/test/3.2 @@ -0,0 +1 @@ +xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5)) diff --git a/test/Main.hs b/test/Main.hs index 9936239..e5bf34d 100644 --- a/test/Main.hs +++ b/test/Main.hs @@ -2,19 +2,29 @@ module Main (main) where import Test.Hspec import Day1 import Day2 +import Day3 main :: IO () main = do - day1in <- readFile "test/1.testcase" - day2in <- readFile "test/2.testcase" hspec $ do describe "Day1" $ do it "solves part 1" $ do - Day1.part1 day1in `shouldBe` "11" + input <- readFile "test/1" + Day1.part1 input `shouldBe` "11" it "solves part 2" $ do - Day1.part2 day1in `shouldBe` "31" + input <- readFile "test/1" + Day1.part2 input `shouldBe` "31" describe "Day 2" $ do it "solves part 1" $ do - Day2.part1 day2in `shouldBe` "2" + input <- readFile "test/2" + Day2.part1 input `shouldBe` "2" it "solves part 2" $ do - Day2.part2 day2in `shouldBe` "4" + input <- readFile "test/2" + Day2.part2 input `shouldBe` "4" + describe "Day 3" $ do + it "solves part 1" $ do + input <- readFile "test/3.1" + Day3.part1 input `shouldBe` "161" + it "solves part 2" $ do + input <- readFile "test/3.2" + Day3.part2 input `shouldBe` "48"