57 lines
1.5 KiB
Haskell
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
|