98e80f4fd6c795aebbcd5c19bdd2232bfaf29760
[advent-of-code-22.git] / advent11 / Main.hs
1 -- Writeup at https://work.njae.me.uk/2022/12/10/advent-of-code-2022-day-9/
2
3 import AoC
4 import Data.Text (Text)
5 import qualified Data.Text.IO as TIO
6 import Data.Attoparsec.Text hiding (take, D)
7 import Control.Applicative
8 import Data.List
9 import qualified Data.IntMap as M
10 import Control.Lens
11
12 data Expression = Expression Operation Operand
13 deriving (Show, Eq)
14 data Operation = Plus | Times deriving (Show, Eq)
15 data Operand = Literal Int | Old deriving (Show, Eq)
16
17 data MonkeyCode = MonkeyCode
18 { _operation :: Expression
19 , _test :: Int
20 , _trueTarget :: Int
21 , _falseTarget :: Int
22 }
23 deriving (Show, Eq)
24 makeLenses ''MonkeyCode
25
26 type MoneyDescription = M.IntMap MonkeyCode
27 type MonkeyHolds = M.IntMap [Int]
28
29
30 main :: IO ()
31 main =
32 do dataFileName <- getDataFileName
33 text <- TIO.readFile dataFileName
34 let monkeys = successfulParse text
35 print monkeys
36 -- let steps = expandPath path
37 -- print $ part1 steps
38 -- print $ part2 steps
39
40 -- part1, part2 :: Path -> Int
41 -- part1 steps = S.size $ rope ^. trace
42 -- where rope = ropeSteps (newRope 1) steps
43
44
45 -- Parse the input file
46
47 -- pathP :: Parser [Direction]
48 -- directionP, upP, leftP, downP, rightP :: Parser Direction
49
50 monkeysP = makeMonkeyMaps <$> (monkeyP `sepBy` (endOfLine <* endOfLine))
51 where makeMonkeyMaps monkeys =
52 ( M.fromList $ map fst monkeys
53 , M.fromList $ map snd monkeys
54 )
55
56 monkeyP = mkMonkeyPair <$> mIdP <*> startingP <*> operationP <*> testP <*> trueTargetP <*> falseTargetP
57 where mkMonkeyPair mId holding _operation _test _trueTarget _falseTarget =
58 ((mId, MonkeyCode{..}), (mId, holding))
59
60 mIdP = ("Monkey " *> decimal) <* ":" <* endOfLine
61 startingP = (" Starting items: " *> (decimal `sepBy` ", ")) <* endOfLine
62 operationP = (" Operation: new = old " *> expressionP) <* endOfLine
63 testP = (" Test: divisible by " *> decimal) <* endOfLine
64 trueTargetP = (" If true: throw to monkey " *> decimal) <* endOfLine
65 falseTargetP = (" If false: throw to monkey " *> decimal)
66
67 expressionP = Expression <$> (operatorP <* " ") <*> operandP
68 operatorP = (Plus <$ "+") <|> (Times <$ "*")
69 operandP = (Literal <$> decimal) <|> (Old <$ "old")
70
71 successfulParse :: Text -> (MoneyDescription, MonkeyHolds)
72 successfulParse input =
73 case parseOnly monkeysP input of
74 Left _err -> (M.empty, M.empty) -- TIO.putStr $ T.pack $ parseErrorPretty err
75 Right monkeys -> monkeys