import Data.Char import Control.Monad total :: Int total = 100 isDigitOrMinus :: Char -> Bool isDigitOrMinus c = isDigit c || c == '-' parse :: [String] -> [Int] parse [_,_,a,_,b,_,c,_,d,_,e] = map (read . takeWhile isDigitOrMinus) [a,b,c,d,e] getall :: [[Int]] -> [Int] getall ing = map fst $ filter cal500 $ map computescore $ allcomb ing where allcomb ing = allcomb' ing 0 allcomb' [] tot = if tot == total then [[0,0,0,0,0]] else [] allcomb' (i:is) tot = concat [map (\x -> map (\(a,b)->am*a+b) $ zip i x) $ allcomb' is (tot+am) | am <- [0..(total-tot)]] computescore x = (product $ map (\x -> if x < 0 then 0 else x) $ init x,last x) cal500 (_,cal) = cal == 500 -- make this function always True for part 1 day15 :: IO () day15 = do input <- liftM (map (parse . words) . lines) $ readFile "day15.txt" --let input = [[-1,-2,6,3],[2,3,-2,-1]] print input let result = maximum $ getall input print result main = day15