From 7cc43b607dcef1958edba80313c0ffdaea5f3aa2 Mon Sep 17 00:00:00 2001 From: Daniele Fucini Date: Fri, 13 Dec 2024 21:46:35 +0100 Subject: [PATCH] Day 13 --- Day13/puzzle1.hs | 31 +++++++++++++++++++++++++++++++ Day13/puzzle2.hs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 Day13/puzzle1.hs create mode 100644 Day13/puzzle2.hs diff --git a/Day13/puzzle1.hs b/Day13/puzzle1.hs new file mode 100644 index 0000000..76eec76 --- /dev/null +++ b/Day13/puzzle1.hs @@ -0,0 +1,31 @@ +import Data.Char (isDigit) +import Data.List.Split (splitOn, chunksOf) +import Data.Matrix (Matrix, fromLists, toList, rref, zero) +import Data.Either (fromRight) +import Data.Maybe (mapMaybe) + +isAlmostInt :: (RealFrac a) => a -> Bool +isAlmostInt x = let diff = x - fromInteger (round x) + in abs diff < 0.000001 + +getMatrix :: (Read a) => String -> Matrix a +getMatrix s = let nValues = map (map read . splitOn ",") . splitOn ":" . drop 1 $ filter (\x -> isDigit x || x == ',' || x == ':') s + eq1 = map head nValues + eq2 = map last nValues + in fromLists [eq1, eq2] + +solve :: (RealFrac a) => Matrix a -> Maybe [a] +solve eqSystem = let rowEchelonList = toList . fromRight (zero 1 1) $ rref eqSystem + solutions = [ rowEchelonList !! 2, rowEchelonList !! 5 ] + in if all isAlmostInt solutions + then Just solutions + else Nothing + +cost :: [Int] -> Int +cost [x, y] = 3 * x + y + +main = do + contents <- map concat . chunksOf 4 . lines <$> readFile "day13.txt" + let eqSystems = map getMatrix contents + solutions = (map . map) round $ mapMaybe solve eqSystems + print . sum $ map cost solutions diff --git a/Day13/puzzle2.hs b/Day13/puzzle2.hs new file mode 100644 index 0000000..690ca9b --- /dev/null +++ b/Day13/puzzle2.hs @@ -0,0 +1,34 @@ +import Data.Char (isDigit) +import Data.List.Split (splitOn, chunksOf) +import Data.Matrix (Matrix, fromLists, toList, rref, zero) +import Data.Either (fromRight) +import Data.Maybe (mapMaybe) + +isAlmostInt :: (RealFrac a) => a -> Bool +isAlmostInt x = let diff = x - fromInteger (round x) + in abs diff < 0.001 + +multRes :: (Num a) => [a] -> [a] +multRes [x, y, z] = [x, y, z + 10000000000000] + +getMatrix :: (Num a, Read a) => String -> Matrix a +getMatrix s = let nValues = map (map read . splitOn ",") . splitOn ":" . drop 1 $ filter (\x -> isDigit x || x == ',' || x == ':') s + eq1 = multRes $ map head nValues + eq2 = multRes $ map last nValues + in fromLists [eq1, eq2] + +solve :: (RealFrac a) => Matrix a -> Maybe [a] +solve eqSystem = let rowEchelonList = toList . fromRight (zero 1 1) $ rref eqSystem + solutions = [ rowEchelonList !! 2, rowEchelonList !! 5 ] + in if all isAlmostInt solutions + then Just solutions + else Nothing + +cost :: [Int] -> Int +cost [x, y] = 3 * x + y + +main = do + contents <- map concat . chunksOf 4 . lines <$> readFile "day13.txt" + let eqSystems = map getMatrix contents + solutions = (map . map) round $ mapMaybe solve eqSystems + print . sum $ map cost solutions