blob: d9a9d178726a3669b726d402909861eee116734e (
plain) (
tree)
|
|
module Solutions.Day11
type Monkey = {
Items: int64 list
Operation: int64 -> int64
Test: int64
TrueMonkey: int
FalseMonkey: int
Inspections: int64
}
let monkeys =
[ { Items = [89; 95; 92; 64; 87; 68]
Operation = (*) 11L
Test = 2
TrueMonkey = 7
FalseMonkey = 4
Inspections = 0 }
{ Items = [87; 67]
Operation = (+) 1L;
Test = 13;
TrueMonkey = 3
FalseMonkey = 6
Inspections = 0 }
{ Items = [95; 79; 92; 82; 60]
Operation = (+) 6L
Test = 3
TrueMonkey = 1
FalseMonkey = 6
Inspections = 0 }
{ Items = [67; 97; 56]
Operation = fun x -> x * x
Test = 17
TrueMonkey = 7
FalseMonkey = 0
Inspections = 0 }
{ Items = [80; 68; 87; 94; 61; 59; 50; 68]
Operation = (*) 7L
Test = 19
TrueMonkey = 5
FalseMonkey = 2
Inspections = 0 }
{ Items = [73; 51; 76; 59]
Operation = (+) 8L
Test = 7
TrueMonkey = 2
FalseMonkey = 1
Inspections = 0 }
{ Items = [92]
Operation = (+) 5L
Test = 11
TrueMonkey = 3
FalseMonkey = 0
Inspections = 0 }
{ Items = [99; 76; 78; 76; 79; 90; 89]
Operation = (+) 7L
Test = 5
TrueMonkey = 4
FalseMonkey = 5
Inspections = 0 } ]
let throw item target monkeys =
let monkey = List.item target monkeys
List.updateAt target {monkey with Items = (List.append monkey.Items [item])} monkeys
let doItem operation monkey monkeys item =
let worryLevel = monkey.Operation item
let boredLevel = operation worryLevel
let target = if boredLevel % monkey.Test = 0L then monkey.TrueMonkey else monkey.FalseMonkey
throw boredLevel target monkeys
let playTurn operation monkeys id =
let monkey = List.item id monkeys
let cleared = monkeys
|> List.updateAt
id
{monkey with Items = []
Inspections = monkey.Inspections + (int64 monkey.Items.Length)}
monkey.Items |> List.fold (doItem operation monkey) cleared
let playRound operation monkeys =
let players = [ 0 .. (List.length monkeys - 1)]
List.fold (playTurn operation) monkeys players
let rec playRounds operation nb monkeys =
if nb = 0 then monkeys
else
let next = playRound operation monkeys
playRounds operation (nb - 1) next
let solve operation count =
monkeys
|> playRounds operation count
|> List.map (fun m -> m.Inspections)
|> List.sortDescending
|> List.take 2
|> List.reduce (*)
let part1 () =
solve (fun x -> x / 3L) 20
let part2 () =
let safeMod = monkeys |> Seq.map (fun m -> m.Test) |> Seq.reduce (*)
solve (fun x -> x % safeMod) 10_000
|