Skip to content

Commit 4d99ce0

Browse files
committed
add day 10 2022
1 parent 879f9c4 commit 4d99ce0

File tree

2 files changed

+187
-0
lines changed

2 files changed

+187
-0
lines changed

inputs/2022/11.txt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
Monkey 0:
2+
Starting items: 53, 89, 62, 57, 74, 51, 83, 97
3+
Operation: new = old * 3
4+
Test: divisible by 13
5+
If true: throw to monkey 1
6+
If false: throw to monkey 5
7+
8+
Monkey 1:
9+
Starting items: 85, 94, 97, 92, 56
10+
Operation: new = old + 2
11+
Test: divisible by 19
12+
If true: throw to monkey 5
13+
If false: throw to monkey 2
14+
15+
Monkey 2:
16+
Starting items: 86, 82, 82
17+
Operation: new = old + 1
18+
Test: divisible by 11
19+
If true: throw to monkey 3
20+
If false: throw to monkey 4
21+
22+
Monkey 3:
23+
Starting items: 94, 68
24+
Operation: new = old + 5
25+
Test: divisible by 17
26+
If true: throw to monkey 7
27+
If false: throw to monkey 6
28+
29+
Monkey 4:
30+
Starting items: 83, 62, 74, 58, 96, 68, 85
31+
Operation: new = old + 4
32+
Test: divisible by 3
33+
If true: throw to monkey 3
34+
If false: throw to monkey 6
35+
36+
Monkey 5:
37+
Starting items: 50, 68, 95, 82
38+
Operation: new = old + 8
39+
Test: divisible by 7
40+
If true: throw to monkey 2
41+
If false: throw to monkey 4
42+
43+
Monkey 6:
44+
Starting items: 75
45+
Operation: new = old * 7
46+
Test: divisible by 5
47+
If true: throw to monkey 7
48+
If false: throw to monkey 0
49+
50+
Monkey 7:
51+
Starting items: 92, 52, 85, 89, 68, 82
52+
Operation: new = old * old
53+
Test: divisible by 2
54+
If true: throw to monkey 0
55+
If false: throw to monkey 1

src/2022/11.zig

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
const std = @import("std");
2+
const aoc = @import("common.zig");
3+
4+
pub fn run(input: aoc.Input) !aoc.Output {
5+
var part1: i64 = 0;
6+
var part2: i64 = 0;
7+
8+
var monkey_lines = aoc.split(input, "\n\n");
9+
var monkeys1 = aoc.newVec(Monkey);
10+
var monkeys2 = aoc.newVec(Monkey);
11+
defer monkeys1.deinit();
12+
defer monkeys2.deinit();
13+
14+
while (monkey_lines.next()) |monkey_line| {
15+
try monkeys1.append(try Monkey.init(monkey_line));
16+
try monkeys2.append(try Monkey.init(monkey_line));
17+
}
18+
defer for (monkeys1.items) |monkey| monkey.deinit();
19+
defer for (monkeys2.items) |monkey| monkey.deinit();
20+
21+
const total_items = blk: {
22+
var total_items: usize = 0;
23+
for (monkeys1.items) |monkey| total_items += monkey.items.items.len;
24+
break :blk total_items;
25+
};
26+
for (monkeys1.items) |*monkey| try monkey.items.ensureTotalCapacity(total_items);
27+
for (monkeys2.items) |*monkey| try monkey.items.ensureTotalCapacity(total_items);
28+
29+
const common_divsor = calculate_common_divisor(&monkeys1);
30+
31+
manage_monkeys(20, true, common_divsor, &monkeys1);
32+
manage_monkeys(10000, false, common_divsor, &monkeys2);
33+
part1 = calculate_monkey_business(&monkeys1);
34+
part2 = calculate_monkey_business(&monkeys2);
35+
36+
return aoc.Output{ .part1 = part1, .part2 = part2 };
37+
}
38+
39+
fn manage_monkeys(comptime rounds: comptime_int, comptime keep_calm: bool, common_divsor: usize, monkeys: *std.ArrayList(Monkey)) void {
40+
for (aoc.range(rounds)) |_| {
41+
for (monkeys.items) |*monkey| {
42+
monkey.inspected += monkey.items.items.len;
43+
for (monkey.items.items) |*item| {
44+
switch (monkey.operation) {
45+
.mul => |amt| item.* *= amt,
46+
.add => |amt| item.* += amt,
47+
.sqr => item.* *= item.*,
48+
}
49+
if (keep_calm) { item.* /= 3; }
50+
else { item.* %= common_divsor; }
51+
const throw_to = if (item.* % monkey.test_div == 0) monkey.if_true else monkey.if_false;
52+
monkeys.items[throw_to].items.appendAssumeCapacity(item.*);
53+
}
54+
monkey.items.clearRetainingCapacity();
55+
}
56+
}
57+
}
58+
59+
fn calculate_monkey_business(monkeys: *std.ArrayList(Monkey)) i64 {
60+
var active1: usize = 0;
61+
var active2: usize = 0;
62+
for (monkeys.items) |monkey| {
63+
if (monkey.inspected > active1) {
64+
active2 = active1;
65+
active1 = monkey.inspected;
66+
} else if (monkey.inspected > active2) {
67+
active2 = monkey.inspected;
68+
}
69+
}
70+
return @intCast(i64, active1 * active2);
71+
}
72+
73+
fn calculate_common_divisor(monkeys: *std.ArrayList(Monkey)) usize {
74+
var a_common_divsor: usize = 1;
75+
for (monkeys.items) |monkey| a_common_divsor *= monkey.test_div;
76+
return a_common_divsor;
77+
}
78+
79+
const Operation = union(enum) {
80+
mul: u8,
81+
add: u8,
82+
sqr: bool,
83+
};
84+
85+
const Monkey = struct {
86+
inspected: usize,
87+
items: std.ArrayList(u64),
88+
operation: Operation,
89+
test_div: u8,
90+
if_true: u8,
91+
if_false: u8,
92+
93+
pub fn init(lines: []const u8) !Monkey {
94+
var monkey_cfg = aoc.tokenize(lines, "\n");
95+
_ = monkey_cfg.next(); // throw away monkey name
96+
const item_line = monkey_cfg.next().?[" Starting items: ".len..];
97+
const oper_line = monkey_cfg.next().?[" Operation: new = old ".len..];
98+
const test_line = monkey_cfg.next().?[" Test: divisible by ".len..];
99+
const true_line = monkey_cfg.next().?[" If true: throw to monkey ".len..];
100+
const false_line = monkey_cfg.next().?[" If false: throw to monkey ".len..];
101+
102+
return Monkey{
103+
.inspected = 0,
104+
.items = blk: {
105+
var items = aoc.newVec(u64);
106+
var item_lines = aoc.tokenize(item_line, ", ");
107+
while (item_lines.next()) |item| try items.append(try std.fmt.parseUnsigned(u8, item, 10));
108+
break :blk items;
109+
},
110+
.operation = switch (oper_line[0]) {
111+
'+' => .{ .add = try std.fmt.parseUnsigned(u8, oper_line[2..], 10) },
112+
'*' => switch (oper_line[2]) {
113+
'o' => .{ .sqr = true },
114+
else => .{ .mul = try std.fmt.parseUnsigned(u8, oper_line[2..], 10) },
115+
},
116+
else => unreachable,
117+
},
118+
.test_div = try std.fmt.parseUnsigned(u8, test_line, 10),
119+
.if_true = try std.fmt.parseUnsigned(u8, true_line, 10),
120+
.if_false = try std.fmt.parseUnsigned(u8, false_line, 10),
121+
};
122+
}
123+
124+
pub fn deinit(self: Monkey) void {
125+
self.items.deinit();
126+
}
127+
};
128+
129+
test "2022-11" {
130+
try aoc.testPart1(0, run(""));
131+
try aoc.testPart2(0, run(""));
132+
}

0 commit comments

Comments
 (0)