solve day 11 :)

This commit is contained in:
ryan 2023-10-08 11:20:44 -07:00
parent c93c273ffd
commit 250d978a38
3 changed files with 140 additions and 147 deletions

View File

@ -10,5 +10,6 @@ let () =
Day7.print ();
Day8.print ();
Day9.print ();
Day10.print ()
Day10.print ();
Day11.print ()
;;

View File

@ -1,146 +1,55 @@
addx 15
addx -11
addx 6
addx -3
addx 5
addx -1
addx -8
addx 13
addx 4
noop
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx -35
addx 1
addx 24
addx -19
addx 1
addx 16
addx -11
noop
noop
addx 21
addx -15
noop
noop
addx -3
addx 9
addx 1
addx -3
addx 8
addx 1
addx 5
noop
noop
noop
noop
noop
addx -36
noop
addx 1
addx 7
noop
noop
noop
addx 2
addx 6
noop
noop
noop
noop
noop
addx 1
noop
noop
addx 7
addx 1
noop
addx -13
addx 13
addx 7
noop
addx 1
addx -33
noop
noop
noop
addx 2
noop
noop
noop
addx 8
noop
addx -1
addx 2
addx 1
noop
addx 17
addx -9
addx 1
addx 1
addx -3
addx 11
noop
noop
addx 1
noop
addx 1
noop
noop
addx -13
addx -19
addx 1
addx 3
addx 26
addx -30
addx 12
addx -1
addx 3
addx 1
noop
noop
noop
addx -9
addx 18
addx 1
addx 2
noop
noop
addx 9
noop
noop
noop
addx -1
addx 2
addx -37
addx 1
addx 3
noop
addx 15
addx -21
addx 22
addx -6
addx 1
noop
addx 2
addx 1
noop
addx -10
noop
noop
addx 20
addx 1
addx 2
addx 2
addx -6
addx -11
noop
noop
noop
Monkey 0:
Starting items: 97, 81, 57, 57, 91, 61
Operation: new = old * 7
Test: divisible by 11
If true: throw to monkey 5
If false: throw to monkey 6
Monkey 1:
Starting items: 88, 62, 68, 90
Operation: new = old * 17
Test: divisible by 19
If true: throw to monkey 4
If false: throw to monkey 2
Monkey 2:
Starting items: 74, 87
Operation: new = old + 2
Test: divisible by 5
If true: throw to monkey 7
If false: throw to monkey 4
Monkey 3:
Starting items: 53, 81, 60, 87, 90, 99, 75
Operation: new = old + 1
Test: divisible by 2
If true: throw to monkey 2
If false: throw to monkey 1
Monkey 4:
Starting items: 57
Operation: new = old + 6
Test: divisible by 13
If true: throw to monkey 7
If false: throw to monkey 0
Monkey 5:
Starting items: 54, 84, 91, 55, 59, 72, 75, 70
Operation: new = old * old
Test: divisible by 7
If true: throw to monkey 6
If false: throw to monkey 3
Monkey 6:
Starting items: 95, 79, 79, 68, 78
Operation: new = old + 3
Test: divisible by 3
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 7:
Starting items: 61, 97, 67
Operation: new = old + 4
Test: divisible by 17
If true: throw to monkey 0
If false: throw to monkey 5

83
src/day11.ml Normal file
View File

@ -0,0 +1,83 @@
open Containers
type monkey =
{ mutable items : int list
; mutable inspected : int
; operation : int -> int
; test : int -> int
; test_num : int
}
let parse_monkeys () =
let lines = Utils.lines_of_input 11 in
let rec parse lines monkeys =
let lines = List.drop_while (String.equal "") lines in
let lines, rest = List.take_drop_while Fun.(String.equal "" %> not) lines in
let lines = List.map Fun.(String.trim %> String.split ~by:" ") lines in
match lines with
| [ [ "Monkey"; _ ]
; "Starting" :: "items:" :: items
; [ "Operation:"; "new"; "="; "old"; op; op_num ]
; [ "Test:"; "divisible"; "by"; test_num ]
; [ "If"; "true:"; "throw"; "to"; "monkey"; if_true ]
; [ "If"; "false:"; "throw"; "to"; "monkey"; if_false ]
] ->
let items =
List.map Fun.(String.replace ~which:`All ~sub:"," ~by:"" %> int_of_string) items
in
let op = if String.equal op "+" then ( + ) else ( * ) in
let operation =
match op_num with
| "old" -> fun old -> op old old
| num -> fun old -> op old @@ int_of_string num
in
let test_num = int_of_string test_num in
let if_true = int_of_string if_true in
let if_false = int_of_string if_false in
let test score = if Int.(score mod test_num) = 0 then if_true else if_false in
let monkey = { items; operation; test; test_num; inspected = 0 } in
parse rest (monkey :: monkeys)
| _ -> monkeys
in
Array.of_list @@ List.rev @@ parse lines []
;;
let throw item monkey = monkey.items <- List.append [ item ] monkey.items
let round monkies manageable =
let divisor = Array.fold_left (fun acc monkey -> acc * monkey.test_num) 1 monkies in
let destress score = if manageable then score / 3 else Int.(score mod divisor) in
monkies
|> Array.iter (fun monkey ->
monkey.items
|> List.iter (fun item ->
let item = destress @@ monkey.operation item in
let throw_to = monkey.test item in
throw item monkies.(throw_to));
monkey.inspected <- monkey.inspected + List.length monkey.items;
monkey.items <- [])
;;
let solve rounds manageable =
let monkies = parse_monkeys () in
for _ = 1 to rounds do
round monkies manageable
done;
monkies
|> Array.to_list
|> List.map (fun monkey -> monkey.inspected)
|> List.sort Int.compare
|> List.rev
|> List.take 2
|> List.reduce ( * )
|> Option.get_exn_or "aoc goofed up the input"
;;
let part1 () = solve 20 true
let part2 () = solve 10_000 false
let print () =
Printf.(
printf "Day 11.1: %d\n" @@ part1 ();
printf "Day 11.2: %d\n" @@ part2 ())
;;