-
Notifications
You must be signed in to change notification settings - Fork 1
/
Program.cs
98 lines (80 loc) · 3.23 KB
/
Program.cs
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using System.Text.RegularExpressions;
using AdventOfCode.Common;
var inputRegex = new Regex(
@"Monkey (?<name>\d):\r?\n" +
@" +Starting items: (?<startingItems>[\d ,]+)\r?\n" +
@" +Operation: new = (?<operation>(old|\d| |\+|\*)+)\r?\n" +
@" +Test: divisible by (?<test>[\d]+)\r?\n" +
@" +If true: throw to monkey (?<trueMonkey>\d+)\r?\n" +
@" +If false: throw to monkey (?<falseMonkey>\d+)",
RegexOptions.Multiline);
var matches = inputRegex.Matches(Resources.GetInputFileContent());
var monkeys1 = new Dictionary<int, Monkey>();
var monkeys2 = new Dictionary<int, Monkey>();
foreach (Match match in matches.Cast<Match>())
{
var name = int.Parse(match.Groups["name"].Value);
var items = match.Groups["startingItems"].Value.Split(", ").Select(ulong.Parse);
var operation = match.Groups["operation"].Value;
var test = ulong.Parse(match.Groups["test"].Value);
var trueMonkey = int.Parse(match.Groups["trueMonkey"].Value);
var falseMonkey = int.Parse(match.Groups["falseMonkey"].Value);
monkeys1.Add(name, new Monkey(items, operation, test, trueMonkey, falseMonkey));
monkeys2.Add(name, new Monkey(items, operation, test, trueMonkey, falseMonkey));
}
static ulong GetMonkeyBusiness(Dictionary<int, Monkey> monkeys, int rounds, Func<ulong, ulong> decreaseWorry)
{
for (int i = 0; i < rounds; i++)
{
foreach (var monkey in monkeys.Values)
{
monkey.Inspect(monkeys, decreaseWorry);
}
}
return monkeys.Values
.Select(m => (ulong)m.Inspections)
.OrderDescending()
.Take(2)
.Aggregate(1UL, (a, b) => a * b);
}
ulong commonMultiplier = monkeys2.Values.Select(m => m.Test).Aggregate((a, b) => a * b);
Console.WriteLine($"Part 1: {GetMonkeyBusiness(monkeys1, 20, item => item / 3)}");
Console.WriteLine($"Part 2: {GetMonkeyBusiness(monkeys2, 10000, item => item % commonMultiplier)}");
class Monkey
{
private readonly ulong? _operand1;
private readonly ulong? _operand2;
private readonly bool _isAddition;
private readonly int _trueMonkey;
private readonly int _falseMonkey;
public Queue<ulong> Items { get; }
public ulong Test { get; }
public int Inspections { get; private set; }
public Monkey(IEnumerable<ulong> items, string operation, ulong test, int trueMonkey, int falseMonkey)
{
Items = new(items);
var parts = operation.Split(" ");
_operand1 = parts[0] == "old" ? null : ulong.Parse(parts[0]);
_operand2 = parts[2] == "old" ? null : ulong.Parse(parts[2]);
_isAddition = parts[1] == "+";
Test = test;
_trueMonkey = trueMonkey;
_falseMonkey = falseMonkey;
}
public void Inspect(Dictionary<int, Monkey> monkeys, Func<ulong, ulong> decreaseWorry)
{
while (Items.TryDequeue(out var item))
{
Inspections++;
item = decreaseWorry(ApplyOperation(item));
monkeys[GetMonkey(item)].Items.Enqueue(item);
}
}
private ulong ApplyOperation(ulong value)
{
var op1 = _operand1 ?? value;
var op2 = _operand2 ?? value;
return _isAddition ? op1 + op2 : op1 * op2;
}
private int GetMonkey(ulong value) => value % Test == 0 ? _trueMonkey : _falseMonkey;
}