48
src/Day7.hs
Normal file
48
src/Day7.hs
Normal file
@@ -0,0 +1,48 @@
|
||||
module Main where
|
||||
|
||||
import qualified AoC as A (extract)
|
||||
import Text.Parsec (char, digit, many1, newline, parse, sepBy1, sepEndBy1, string)
|
||||
import Text.Parsec.String (Parser)
|
||||
|
||||
type Equation = (Int, [Int])
|
||||
|
||||
type Operator = Int -> Int -> Int
|
||||
|
||||
parseEqns :: Parser [Equation]
|
||||
parseEqns = parseEqn `sepEndBy1` newline
|
||||
where
|
||||
parseEqn :: Parser Equation
|
||||
parseEqn =
|
||||
(,)
|
||||
<$> (read <$> many1 digit <* string ": ")
|
||||
<*> (read <$> many1 digit) `sepBy1` char ' '
|
||||
|
||||
-- concatenate integers
|
||||
cc :: Operator
|
||||
cc a b = a * (10 ^ length b) + b
|
||||
where
|
||||
-- this is faster than log_10
|
||||
length :: Int -> Int
|
||||
length 0 = 0
|
||||
length x = 1 + length (x `div` 10)
|
||||
|
||||
check :: [Operator] -> Equation -> Bool
|
||||
check operators (target, operand : operands) = go operand operands
|
||||
where
|
||||
go :: Int -> [Int] -> Bool
|
||||
go i [] = i == target
|
||||
go i (x : xs)
|
||||
| i > target = False -- prune
|
||||
| otherwise = any (\op -> go (i `op` x) xs) operators
|
||||
|
||||
getSum :: [Operator] -> [Equation] -> Int
|
||||
getSum ops = sum . map fst . filter (check ops)
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
do
|
||||
raw <- readFile "./inputs/day7.in"
|
||||
let equations = A.extract $ parse parseEqns "" raw
|
||||
|
||||
putStr "Part 1: " >> print (getSum [(+), (*)] equations)
|
||||
putStr "Part 2: " >> print (getSum [(+), (*), cc] equations)
|
Reference in New Issue
Block a user