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