diff --git a/advent-of-code-2022.csproj b/advent-of-code-2022.csproj index 3cf0498..4e07177 100644 --- a/advent-of-code-2022.csproj +++ b/advent-of-code-2022.csproj @@ -54,6 +54,7 @@ + diff --git a/inputs/11.txt b/inputs/11.txt index 328ac4f..80fe847 100644 --- a/inputs/11.txt +++ b/inputs/11.txt @@ -1,10 +1,55 @@ -3265255276 -1537412665 -7335746422 -6426325658 -3854434364 -8717377486 -4522286326 -6337772845 -8824387665 -6351586484 \ No newline at end of file +Monkey 0: + Starting items: 62, 92, 50, 63, 62, 93, 73, 50 + Operation: new = old * 7 + Test: divisible by 2 + If true: throw to monkey 7 + If false: throw to monkey 1 + +Monkey 1: + Starting items: 51, 97, 74, 84, 99 + Operation: new = old + 3 + Test: divisible by 7 + If true: throw to monkey 2 + If false: throw to monkey 4 + +Monkey 2: + Starting items: 98, 86, 62, 76, 51, 81, 95 + Operation: new = old + 4 + Test: divisible by 13 + If true: throw to monkey 5 + If false: throw to monkey 4 + +Monkey 3: + Starting items: 53, 95, 50, 85, 83, 72 + Operation: new = old + 5 + Test: divisible by 19 + If true: throw to monkey 6 + If false: throw to monkey 0 + +Monkey 4: + Starting items: 59, 60, 63, 71 + Operation: new = old * 5 + Test: divisible by 11 + If true: throw to monkey 5 + If false: throw to monkey 3 + +Monkey 5: + Starting items: 92, 65 + Operation: new = old * old + Test: divisible by 5 + If true: throw to monkey 6 + If false: throw to monkey 3 + +Monkey 6: + Starting items: 78 + Operation: new = old + 8 + Test: divisible by 3 + If true: throw to monkey 0 + If false: throw to monkey 7 + +Monkey 7: + Starting items: 84, 93, 54 + Operation: new = old + 1 + Test: divisible by 17 + If true: throw to monkey 2 + If false: throw to monkey 1 \ No newline at end of file diff --git a/inputs/11a.txt b/inputs/11a.txt new file mode 100644 index 0000000..e888add --- /dev/null +++ b/inputs/11a.txt @@ -0,0 +1,27 @@ +Monkey 0: + Starting items: 79, 98 + Operation: new = old * 19 + Test: divisible by 23 + If true: throw to monkey 2 + If false: throw to monkey 3 + +Monkey 1: + Starting items: 54, 65, 75, 74 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 2 + If false: throw to monkey 0 + +Monkey 2: + Starting items: 79, 60, 97 + Operation: new = old * old + Test: divisible by 13 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 74 + Operation: new = old + 3 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 1 \ No newline at end of file diff --git a/src/11.cs b/src/11.cs new file mode 100644 index 0000000..50be4e8 --- /dev/null +++ b/src/11.cs @@ -0,0 +1,131 @@ +namespace aoc2022; + +internal class Day11 : Day +{ + private class monkey + { + public readonly Queue startingItems = new(); + public Queue items = new(); + public string operation = string.Empty; + public long testDivBy; + public int trueTarget; + public int falseTarget; + public long timesInspected; + } + + private readonly List monkeys = new(); + private long divideByProduct = 1; + + internal override void Parse() + { + monkey? m = null; + foreach (var line in Util.Parsing.ReadAllLines("11")) + { + if (line.StartsWith("Monkey")) + { + m = new monkey(); + monkeys.Add(m); + } + else if (line.Trim().StartsWith("Starting items")) + { + var parts = line.Split(':'); + var items = parts[1].Split(','); + foreach (var item in items) + { + m!.startingItems.Enqueue(int.Parse(item.Trim())); + } + } + else if (line.Trim().StartsWith("Operation")) + { + m!.operation = line.Split(':')[1].Trim()["new = ".Length..]; + } + else if (line.Trim().StartsWith("Test")) + { + m!.testDivBy = int.Parse(line.Trim().Split(' ')[3]); + divideByProduct *= m.testDivBy; + } + else if (line.Trim().StartsWith("If true")) + { + m!.trueTarget = int.Parse(line.Trim().Split(' ')[5]); + } + else if (line.Trim().StartsWith("If false")) + { + m!.falseTarget = int.Parse(line.Trim().Split(' ')[5]); + } + } + } + + private void monkeyRound(Func worryReducer) + { + foreach (var m in monkeys) + { + while (m.items.Count > 0) + { + long item = m.items.Dequeue(); + + long[] operands = new long[2]; + var op = m.operation.Replace("old", $"{item}"); + var parts = op.Split(' '); + operands[0] = long.Parse(parts.First()); + operands[1] = long.Parse(parts.Last()); + if (m.operation.Contains('*')) + { + item = operands[0] * operands[1]; + } + else + { + item = operands[0] + operands[1]; + } + + item = worryReducer(item); + + if (item % m.testDivBy == 0) + { + monkeys[m.trueTarget].items.Enqueue(item); + } + else + { + monkeys[m.falseTarget].items.Enqueue(item); + } + + m.timesInspected++; + } + } + } + + internal override string Part1() + { + monkeys.ForEach(m => + { + m.timesInspected = 0; + m.items = new(m.startingItems); + }); + for (int round = 0; round < 20; round++) + { + monkeyRound(worry => worry / 3); + } + + var sorted = monkeys.OrderByDescending(m => m.timesInspected); + var monkeyBusiness = sorted.Take(2).Aggregate(1L, (x, y) => x * y.timesInspected); + return $"Monkey business after 20 rounds, dividing worry by 3: <+white>{monkeyBusiness}"; + } + + internal override string Part2() + { + // still hurting for a deep copy utility... + monkeys.ForEach(m => + { + m.timesInspected = 0; + m.items = new(m.startingItems); + }); + + for (int round = 0; round < 10000; round++) + { + monkeyRound(worry => worry % divideByProduct); + } + + var sorted = monkeys.OrderByDescending(m => m.timesInspected); + var monkeyBusiness = sorted.Take(2).Aggregate(1L, (x, y) => x * y.timesInspected); + return $"Monkey business after 10,000 rounds, reducing worry 'another way': <+white>{monkeyBusiness}"; + } +} \ No newline at end of file