From 3294353d22b934cfd7cd8e72e1892cd187218bd9 Mon Sep 17 00:00:00 2001 From: RhiobeT Date: Mon, 11 Dec 2023 11:53:59 +0100 Subject: [PATCH] Day 11 --- advent-of-code-2023.cabal | 8 +++++++ day11/Commons.hs | 46 +++++++++++++++++++++++++++++++++++++++ day11/Main.hs | 12 ++++++++++ day11/Part1.hs | 8 +++++++ day11/Part2.hs | 8 +++++++ 5 files changed, 82 insertions(+) create mode 100644 day11/Commons.hs create mode 100644 day11/Main.hs create mode 100644 day11/Part1.hs create mode 100644 day11/Part2.hs diff --git a/advent-of-code-2023.cabal b/advent-of-code-2023.cabal index 9f9db43..c7f6822 100644 --- a/advent-of-code-2023.cabal +++ b/advent-of-code-2023.cabal @@ -84,3 +84,11 @@ executable day10 build-depends: base ^>=4.15.1.0, array hs-source-dirs: day10 default-language: Haskell2010 + +executable day11 + main-is: Main.hs + other-modules: Commons Part1 Part2 + + build-depends: base ^>=4.15.1.0, array, Unique + hs-source-dirs: day11 + default-language: Haskell2010 diff --git a/day11/Commons.hs b/day11/Commons.hs new file mode 100644 index 0000000..26fcd99 --- /dev/null +++ b/day11/Commons.hs @@ -0,0 +1,46 @@ +module Commons where + +import GHC.IO.Handle (isEOF) +import Data.Array (Array, listArray, (!), indices) +import Data.List.Unique (sortUniq) + + +type Image = [(Int, Int)] +type ExpansionArray = Array Int Int + + +parseLine :: Int -> Int -> String -> Image +parseLine _ _ [] = [] +parseLine row column ('#': t) = (column, row): parseLine row (column + 1) t +parseLine row column (_: t) = parseLine row (column + 1) t + +parseImage :: Int -> Image -> IO Image +parseImage row image = do done <- isEOF + if done + then return image + else do line <- getLine + parseImage (row + 1) (image ++ parseLine row 1 line) + +parse :: IO Image +parse = parseImage 1 [] + + +getExpansionArray :: Int -> Int -> Int -> [Int] -> [Int] +getExpansionArray _ _ _ [] = [] +getExpansionArray i expOffset expInc (h: t) + | i == h = i + expOffset: getExpansionArray (i + 1) expOffset expInc t + | i < h = i + expOffset: getExpansionArray (i + 1) (expOffset + expInc) expInc (h: t) + +getExpansionArrays :: Int -> Image -> (ExpansionArray, ExpansionArray) +getExpansionArrays expInc image = let expX = getExpansionArray 1 0 expInc $ sortUniq . map fst $ image + expY = getExpansionArray 1 0 expInc $ sortUniq . map snd $ image + in (listArray (1, length expX) expX, listArray (1, length expY) expY) + +getDistancesGalaxy :: Image -> (ExpansionArray, ExpansionArray) -> (Int, Int) -> [Int] +getDistancesGalaxy [] _ _ = [] +getDistancesGalaxy ((x0, y0): t) (expX, expY) (x1, y1) = + abs ((expX ! x0) - (expX ! x1)) + abs ((expY ! y0) - (expY ! y1)): getDistancesGalaxy t (expX, expY) (x1, y1) + +getDistances :: Image -> (ExpansionArray, ExpansionArray) -> [[Int]] +getDistances [] _ = [] +getDistances (h: t) (expX, expY) = getDistancesGalaxy t (expX, expY) h: getDistances t (expX, expY) diff --git a/day11/Main.hs b/day11/Main.hs new file mode 100644 index 0000000..f6ff7b3 --- /dev/null +++ b/day11/Main.hs @@ -0,0 +1,12 @@ +module Main where + +import Commons +import qualified Part1 +import qualified Part2 + + +main = do image <- parse + let part1Res = sum . concat $ Part1.computeDistances image + print part1Res + let part2Res = sum . concat $ Part2.computeDistances image + print part2Res diff --git a/day11/Part1.hs b/day11/Part1.hs new file mode 100644 index 0000000..7e66297 --- /dev/null +++ b/day11/Part1.hs @@ -0,0 +1,8 @@ +module Part1 where + +import Commons + + +computeDistances :: Image -> [[Int]] +computeDistances image = let expansionArrays = getExpansionArrays 1 image + in getDistances image expansionArrays diff --git a/day11/Part2.hs b/day11/Part2.hs new file mode 100644 index 0000000..aff1220 --- /dev/null +++ b/day11/Part2.hs @@ -0,0 +1,8 @@ +module Part2 where + +import Commons + + +computeDistances :: Image -> [[Int]] +computeDistances image = let expansionArrays = getExpansionArrays 999999 image + in getDistances image expansionArrays