From a588555cbc4c0f1647ee12ce619e4135003def1b Mon Sep 17 00:00:00 2001 From: Annwan Date: Tue, 3 Dec 2024 14:18:25 +0100 Subject: [PATCH] Day 3 (regex go brrrrrr) Also some housekeeping --- aoc2024.cabal | 6 ++++-- run/Main.hs | 7 +++++-- src/Day3.hs | 34 ++++++++++++++++++++++++++++++++++ test/{1.testcase => 1} | 0 test/{2.testcase => 2} | 0 test/3.1 | 1 + test/3.2 | 1 + test/Main.hs | 22 ++++++++++++++++------ 8 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 src/Day3.hs rename test/{1.testcase => 1} (100%) rename test/{2.testcase => 2} (100%) create mode 100644 test/3.1 create mode 100644 test/3.2 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"