From 8b597d35b9ead1ef45c635c61683449a1ef65e5d Mon Sep 17 00:00:00 2001 From: Hans Goor Date: Sun, 8 Dec 2024 16:43:10 +0100 Subject: [PATCH] Add solution to day 8. --- 2024/haskell/app/day8/Day8.hs | 60 +++++++++++++++++++++++++ 2024/haskell/haskell.cabal | 14 ++++++ 2024/haskell/package.yaml | 10 +++++ 2024/haskell/resources/day8.txt | 50 +++++++++++++++++++++ 2024/haskell/resources/day8_example.txt | 12 +++++ 5 files changed, 146 insertions(+) create mode 100644 2024/haskell/app/day8/Day8.hs create mode 100644 2024/haskell/resources/day8.txt create mode 100644 2024/haskell/resources/day8_example.txt diff --git a/2024/haskell/app/day8/Day8.hs b/2024/haskell/app/day8/Day8.hs new file mode 100644 index 0000000..c59c2a3 --- /dev/null +++ b/2024/haskell/app/day8/Day8.hs @@ -0,0 +1,60 @@ +module Main (main) where + +import Data.List (groupBy, nub, sort, sortBy, subsequences) +import Data.Maybe (catMaybes) + +-- | Part 1 +data Antenna = Antenna Char (Int, Int) deriving (Show, Eq) + +coords :: Antenna -> (Int, Int) +coords (Antenna _ (x, y)) = (x, y) + +findAntennas :: [[Char]] -> [Antenna] +findAntennas grid = + let possibilities = [maybeAntenna (row, col) | row <- [0 .. length grid - 1], col <- [0 .. length (grid !! row) - 1]] + in catMaybes possibilities + where + maybeAntenna :: (Int, Int) -> Maybe Antenna + maybeAntenna (row, col) + | (grid !! row) !! col == '.' = Nothing + | otherwise = Just (Antenna ((grid !! row) !! col) (row, col)) + +calculateAntiNodes :: (Int, Int) -> (Int, Int) -> [(Int, Int)] +calculateAntiNodes (xa, ya) (xb, yb) = + let (dx, dy) = (xb - xa, yb - ya) + in [(xa - dx, ya - dy), (xb + dx, yb + dy)] + +allAntiNodes :: [(Int, Int)] -> [(Int, Int)] +allAntiNodes antennas = concatMap (uncurry calculateAntiNodes . (\[a, b] -> (a, b))) $ filter ((2 ==) . length) $ subsequences antennas + +outOfBounds :: [[a]] -> (Int, Int) -> Bool +outOfBounds g (row, col) = row < 0 || row >= length g || col < 0 || col >= length (g !! row) + +part1 :: String -> IO () +part1 s = + let grid = lines s + antennas = findAntennas grid + groupedAntennas = (groupBy (\(Antenna a _) (Antenna b _) -> a == b) . sortBy (\(Antenna a _) (Antenna b _) -> compare a b)) antennas + antiNodes = concatMap (filter (not . outOfBounds grid) . allAntiNodes . map coords) groupedAntennas + in print $ length $ nub antiNodes + +-- | Part 2 +multiplesAN :: [[a]] -> (Int, Int) -> (Int, Int) -> [(Int, Int)] +multiplesAN grid (xa, ya) (xb, yb) = + let (dx, dy) = (xb - xa, yb - ya) + in (takeWhile (not . outOfBounds grid) [(xa - dx * i, ya - dy * i) | i <- [0 ..]]) ++ takeWhile (not . outOfBounds grid) [(xb + dx * i, yb + dy * i) | i <- [0 ..]] + +allMultiplesAN :: [[a]] -> [(Int, Int)] -> [(Int, Int)] +allMultiplesAN grid antennas = foldr (\[a, b] l -> multiplesAN grid a b ++ l) [] $ filter ((2 ==) . length) $ subsequences antennas + +part2 :: String -> IO () +part2 s = + let grid = lines s + antennas = findAntennas grid + groupedAntennas = (groupBy (\(Antenna a _) (Antenna b _) -> a == b) . sortBy (\(Antenna a _) (Antenna b _) -> compare a b)) antennas + antiNodes = concatMap (allMultiplesAN grid . map coords) groupedAntennas + in print $ length $ nub antiNodes + +-- | Main +main :: IO () +main = readFile "resources/day8.txt" >>= part2 diff --git a/2024/haskell/haskell.cabal b/2024/haskell/haskell.cabal index 75ec3d9..3b091db 100644 --- a/2024/haskell/haskell.cabal +++ b/2024/haskell/haskell.cabal @@ -138,6 +138,20 @@ executable day7 , parallel default-language: Haskell2010 +executable day8 + main-is: Day8.hs + other-modules: + Paths_haskell + autogen-modules: + Paths_haskell + hs-source-dirs: + app/day8 + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N + build-depends: + base >=4.7 && <5 + , haskell + default-language: Haskell2010 + test-suite haskell-test type: exitcode-stdio-1.0 main-is: Spec.hs diff --git a/2024/haskell/package.yaml b/2024/haskell/package.yaml index 41d200d..db06143 100644 --- a/2024/haskell/package.yaml +++ b/2024/haskell/package.yaml @@ -109,6 +109,16 @@ executables: - haskell - parallel + day8: + main: Day8.hs + source-dirs: app/day8 + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + dependencies: + - haskell + tests: haskell-test: main: Spec.hs diff --git a/2024/haskell/resources/day8.txt b/2024/haskell/resources/day8.txt new file mode 100644 index 0000000..5b15221 --- /dev/null +++ b/2024/haskell/resources/day8.txt @@ -0,0 +1,50 @@ +...............e...........j6..................... +.....1...............................t.....i...... +.....4.......3..............x..tL......m.......... +.......L.....................Dxj.................. +4....X..................F.....................m... +.............4.......x....F........k.............. +......3...................t..........i.........Z.. +....L..................y.....F..e.....Z........... +X.............1........C..........i...D........... +........4.....................D.....k.X...m....... +...1...............D........e......6.............. +...3.Y...................................m8....... +..OL.........................x....Z....g.......... +....3......5.........................6j........... +...................J..5r.F..k...y................. +.......................................Z..a....... +...........................5........j.........a.u. +...p..............Y....X.......................... +...O.........................kd................... +........................t.................i....... +..................J..............u...........z.... +.O.....9.............J..............p..u.......... +.....9............................................ +l...6.....1........e......I................a...... +...................................az............. +........M.......J...................gI....z....... +.......Y...l...........p......g....d.......W...... +........5l....9................d.....g............ +.A....9.l.Y............I..............B.......s... +..................................K.....B......... +....M.............7.......8..........h.....K...... +.......0f...oc..............G...d7.......z...s..yW +...M........0...........Gf.....................T.. +................r......G..................w....h.. +...........cP................G.8.R..............T. +.................A.............N............u..B.. +..H.c..b............................K...CB.....y.. +......c...bP...2............7..K.................. +......b.o....0.......P.............s........h.R... +......2........f..S........8.....................R +U....2..............p..............7.............. +.HE..b......A.............N..............w....C... +................................N.............w... +.........E...........M................W.......T... +......E...rS2...........W....................N.... +.....SP..n.....r..0............................... +.....H..............A............................w +..........n..U....................s............... +..n.So.....U................f..................... +Ho................................................ diff --git a/2024/haskell/resources/day8_example.txt b/2024/haskell/resources/day8_example.txt new file mode 100644 index 0000000..78a1e91 --- /dev/null +++ b/2024/haskell/resources/day8_example.txt @@ -0,0 +1,12 @@ +............ +........0... +.....0...... +.......0.... +....0....... +......A..... +............ +............ +........A... +.........A.. +............ +............