Skip to content

Commit a002ff4

Browse files
committed
Day 7 (Haskell)
1 parent fbc2f49 commit a002ff4

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

src/day07.hs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{-# LANGUAGE TupleSections #-}
2+
{-# LANGUAGE ViewPatterns #-}
3+
4+
import Control.Monad.Zip (mzip)
5+
import Data.List (singleton)
6+
import Data.List.Split (splitOn)
7+
import Data.Tree
8+
9+
data Equation = Equation {result :: Int, terms :: [Int]} deriving (Show)
10+
11+
instance Read Equation where
12+
readsPrec _ (splitOn ":" -> [lhs, rhs]) =
13+
let result = read lhs
14+
terms = map read $ words rhs
15+
in [(Equation {result = result, terms = terms}, "")]
16+
readsPrec _ _ = []
17+
18+
data Operator = Add | Multiply | Concat | Init deriving (Show)
19+
20+
operators :: Tree Operator
21+
operators = unfoldTree (,[Add, Multiply, Concat]) Init
22+
23+
toLayers :: [a] -> Tree a
24+
toLayers (x : xs) = unfoldTree f (x, xs)
25+
where
26+
f (current, []) = (current, [])
27+
f (current, next : rest) = (current, repeat (next, rest))
28+
29+
evalExpr :: Int -> Operator -> Int -> Int
30+
evalExpr _ Init a = a
31+
evalExpr a Add b = a + b
32+
evalExpr a Multiply b = a * b
33+
evalExpr a Concat b = a * o + b
34+
where
35+
o = head (dropWhile (b >=) [10 ^ x | x <- [0 ..]])
36+
37+
interimResults :: [Int] -> Tree Int
38+
interimResults terms = scanTree (uncurry . evalExpr) 0 (mzip operators (toLayers terms))
39+
40+
isSatisfyable :: Equation -> Bool
41+
isSatisfyable (Equation r ts) = elem r $ takeWhileTree (r >=) $ interimResults ts
42+
43+
main = do
44+
contents <- readFile "input7.txt"
45+
let equations = (map read $ lines contents) :: [Equation]
46+
putStrLn "Part 2:"
47+
print $ sum $ map result $ filter isSatisfyable equations
48+
49+
scanTree :: (b -> a -> b) -> b -> Tree a -> Tree b
50+
scanTree f s t = unfoldTree unfoldF (s, t)
51+
where
52+
unfoldF (acc, Node r sf) = (res, map (res,) sf)
53+
where
54+
res = f acc r
55+
56+
takeWhileTree :: (a -> Bool) -> Tree a -> Tree a
57+
takeWhileTree p = head . unfoldForest unfoldF . singleton
58+
where
59+
unfoldF (Node r sf) = (r, filter (p . rootLabel) sf)

0 commit comments

Comments
 (0)