blob: 383705493442de87444b08adac915bd4ff26b5cd (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
module Day21
open System.IO
open FSharpPlus
open FParsec
open Common
type MonkeyName = string
type Operator = int64 -> int64 -> int64
type MonkeyJob =
| Number of int64
| Operation of MonkeyName * Operator * MonkeyName
static member dependencies =
function
| Number _ -> []
| Operation (l, _, r) -> [ l; r ]
type Monkey = MonkeyName * MonkeyJob
let charToOperator =
function
| '+' -> (+)
| '-' -> (-)
| '*' -> (*)
| '/' -> (/)
| c -> failwithf "Invalid operator: %c" c
let parseMonkey =
let pspc = pchar ' '
let pname = anyString 4 |>> MonkeyName
let poper = pspc >>. anyChar .>> pspc |>> charToOperator
let pnumber = pint64 |>> Number
let poperation = tuple3 pname poper pname |>> Operation
let pjob = pnumber <|> poperation
let pmonkey = pname .>> pstring ": " .>>. pjob |>> Monkey
Util.parse pmonkey
let solution input =
let monkeys = input |> Seq.map parseMonkey |> Map.ofSeq
monkeys
|> Map.mapValues MonkeyJob.dependencies
|> Util.tsort
|> List.fold
(fun values name ->
Map.add
name
(match monkeys[name] with
| Number num -> num
| Operation (left, operator, right) -> operator values[left] values[right])
values)
Map.empty
|> Map.find "root"
let test = File.ReadLines("test.txt")
assert (solution test = 152)
let input = File.ReadLines("input.txt")
printfn "%d" <| solution input
|