From 2f0505d52f183a69d9216e7da7b4426238cdf1f3 Mon Sep 17 00:00:00 2001 From: Maciej Jur Date: Sun, 3 Dec 2023 20:02:28 +0100 Subject: [PATCH] haskell: 2023 03 b --- 2023/haskell/app/Main.hs | 2 +- 2023/haskell/solutions/Day03.hs | 24 +++++++++++++++--------- 2023/haskell/tests/Main.hs | 7 +++++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/2023/haskell/app/Main.hs b/2023/haskell/app/Main.hs index a07cdf0..8454704 100644 --- a/2023/haskell/app/Main.hs +++ b/2023/haskell/app/Main.hs @@ -28,7 +28,7 @@ day03 = do Left err -> putStrLn err Right xd -> do print . Day03.solveA $ xd - --print . Day02.solveB $ xd + print . Day03.solveB $ xd main :: IO () main = do diff --git a/2023/haskell/solutions/Day03.hs b/2023/haskell/solutions/Day03.hs index 9bbb66c..b8d902b 100644 --- a/2023/haskell/solutions/Day03.hs +++ b/2023/haskell/solutions/Day03.hs @@ -5,9 +5,9 @@ import Data.Bifunctor (first, second) import Data.Void (Void) import Data.Char (digitToInt, isSpace) import Data.Text (Text) +import Data.Maybe (mapMaybe) import Text.Megaparsec (errorBundlePretty, Parsec, runParser, many, eof, choice, satisfy, manyTill) import Text.Megaparsec.Char (digitChar, char) -import Data.Maybe (mapMaybe) data Item @@ -51,12 +51,12 @@ findSpans = helper [] withCoords :: [[a]] -> [((Row, Col), a)] withCoords grid = [((r, c), a) | (r, row) <- zip [0..] grid, (c, a) <- zip [0..] row] -getSymbols :: Grid -> [(Row, Col)] +getSymbols :: Grid -> [(Char, (Row, Col))] getSymbols = mapMaybe isSymbol . withCoords where - isSymbol :: ((Row, Col), Item) -> Maybe (Row, Col) + isSymbol :: ((Row, Col), Item) -> Maybe (Char, (Row, Col)) isSymbol (rc, item) = case item of - Symbol _ -> Just rc + Symbol s -> Just (s, rc) _ -> Nothing getNumbers :: Grid -> [(Int, (Row, Col, Col))] @@ -82,15 +82,21 @@ getNeigbors (r, s, e) = [(r, s-1), (r, e+1)] <> [(r-1, c) | c <- [s-1..e+1]] <> [(r+1, c) | c <- [s-1..e+1]] -solveA :: [[Item]] -> Int +solveA :: Grid -> Int solveA grid = - let symbols = getSymbols grid + let symbols = map snd $ getSymbols grid numbers = getNumbers grid - in sum . map fst . filter (hasSymbol symbols . snd) . map (second getNeigbors) $ numbers + in sum . map fst . filter (hasSymbol symbols . getNeigbors . snd) $ numbers where hasSymbol :: [(Row, Col)] -> [(Row, Col)] -> Bool hasSymbol symbols = any (`elem` symbols) -solveB :: [[Item]] -> Int -solveB = undefined +solveB :: Grid -> Int +solveB grid = + let symbols = map snd . filter (('*'==) . fst) $ getSymbols grid + numbers = map (second getNeigbors) $ getNumbers grid + in sum . map product . filter ((2==) . length) . map (findNumbers numbers) $ symbols + where + findNumbers :: [(Int, [(Row, Col)])] -> (Row, Col) -> [Int] + findNumbers ns symbol = map fst . filter ((symbol `elem`) . snd) $ ns diff --git a/2023/haskell/tests/Main.hs b/2023/haskell/tests/Main.hs index ec10d00..f9b7b8a 100644 --- a/2023/haskell/tests/Main.hs +++ b/2023/haskell/tests/Main.hs @@ -32,8 +32,11 @@ day02 = TestList ] day03 :: Test -day03 = TestList - [ TestCase $ assertEqual "A" (Right 4361) (Day03.solveA <$> Day03.parse input) +day03 = + let parsed = Day03.parse input + in TestList + [ TestCase $ assertEqual "A" (Right 4361) (Day03.solveA <$> parsed) + , TestCase $ assertEqual "B" (Right 467835) (Day03.solveB <$> parsed) ] where input =