advent-of-code-2025/03/solution.hs

57 lines
1.5 KiB
Haskell

import Debug.Trace
import Data.Maybe
import Control.Applicative
instance (Applicative m, Num a) => Num (m a) where
(+) = liftA2 (+)
(-) = liftA2 (-)
(*) = liftA2 (*)
abs = fmap abs
signum = fmap signum
negate = fmap negate
fromInteger = pure . fromInteger
traceOut :: Show a => a -> a
traceOut x = traceShow x x
addFirst :: [[a]] -> a -> [[a]]
addFirst [] x = [[x]]
addFirst (y:ys) x = ([x] ++ y) : ys
split :: Eq a => [a] -> [a] -> [[a]]
split _ [] = []
split delims (x:xs)
| elem x delims = [[]] ++ split delims xs
| otherwise = addFirst (split delims xs) x
parseFile :: String -> [[Int]]
parseFile = map (map (read . (:[]))) . split ['\n']
dropLast :: Int -> [a] -> [a]
dropLast n = reverse . drop n . reverse
takeAfter :: (a -> Bool) -> [a] -> [a]
takeAfter f [] = []
takeAfter f (x:xs) = if f x then xs else takeAfter f xs
listMax :: Ord a => [a] -> Maybe a
listMax [] = Nothing
listMax (x:xs) = Just $ foldl max x xs
bestJoltage :: Int -> [Int] -> Maybe Int
bestJoltage n xs
| n <= 0 = 0
| null (drop (n-1) xs) = 0
| otherwise = case maximum of Nothing -> Nothing; Just maximum' -> 10^(n-1) * maximum + (bestJoltage (n-1) (takeAfter (>= maximum') xs))
where maximum = listMax $ dropLast (n-1) xs
solve :: Int -> [[Int]] -> Maybe Int
solve n = fmap sum . sequence . map (bestJoltage n)
main = do
fileinp <- readFile "input.txt"
let input = parseFile fileinp
let solved1 = fromJust $ solve 2 input
let solved2 = fromJust $ solve 12 input
print solved1
print solved2