advent-of-code-2024/7/solution.hs

50 lines
1.7 KiB
Haskell

import Data.List
import Debug.Trace
addFirst :: [[a]] -> a -> [[a]]
addFirst [] x = [[x]]
addFirst (y:ys) x = ([x] ++ y) : ys
split :: [Char] -> [Char] -> [[Char]]
split _ [] = []
split delims (x:xs)
| elem x delims = [[]] ++ split delims xs
| otherwise = addFirst (split delims xs) x
splitInput :: String -> [(Int, [Int])]
splitInput text = map (\(x:xs) -> (x, xs)) $ map (map read) $ map (filter (/="")) $ map (split [' ', ':']) $ split ['\n'] text
solve1 :: [(Int, [Int])] -> Int
solve1 [] = 0
solve1 ((_, []):xs) = solve1 xs
solve1 ((a, (b:bs)):xs) = ((\x -> if x then 0 else a) $ null $ filter (==a) $ map (\fs -> (foldl' (flip ($)) b (zipWith flip fs bs))) (getOperators (length bs))) + solve1 xs
getOperators :: (Num a, Show a) => Int -> [[(a -> a -> a)]]
getOperators 0 = [[]]
getOperators x
| x < 0 = [[]]
| otherwise = (map (\x -> (+):x) (getOperators (x-1))) ++ (map (\x -> (*):x) (getOperators (x-1)))
solve2 :: [(Int, [Int])] -> Int
solve2 [] = 0
solve2 ((_, []):xs) = solve2 xs
solve2 ((a, (b:bs)):xs) = ((\x -> if x then 0 else a) $ null $ filter (==a) $ map (\fs -> (foldl' (flip ($)) b (zipWith flip fs bs))) (getOperators2 (length bs))) + solve2 xs
getOperators2 :: (Num a, Show a, Read a) => Int -> [[(a -> a -> a)]]
getOperators2 0 = [[]]
getOperators2 x
| x < 0 = [[]]
| otherwise = (map (\x -> (+):x) (getOperators2 (x-1))) ++ (map (\x -> (*):x) (getOperators2 (x-1))) ++ (map (\x -> concat':x) (getOperators2 (x-1)))
concat' :: (Show a, Read a) => a -> a -> a
concat' x y = read ((show x) ++ (show y))
main :: IO()
main = do
fileinp <- readFile "input.txt"
let parsed = splitInput fileinp
let solved1 = solve1 parsed
let solved2 = solve2 parsed
print solved1
print solved2