Add day 11 part 2

This commit is contained in:
2022-12-15 09:03:11 +01:00
parent a985d2e00c
commit fd794bab16

View File

@@ -6,15 +6,15 @@ namespace AdventOfCode.Days;
public class Monkey
{
public int Number { get; }
public int InspectionCount { get; private set; }
public long InspectionCount { get; private set; }
private readonly Queue<int> _items;
private readonly Func<int, int> _operation;
private readonly int _testDivider;
private readonly Queue<long> _items;
private readonly Func<long, long> _operation;
private readonly long _testDivider;
private readonly int _testFailMonkey;
private readonly int _testSuccessMonkey;
public Monkey(int number, IEnumerable<int> items, Func<int, int> operation, int testDivider, int testFailMonkey, int testSuccessMonkey)
public Monkey(int number, IEnumerable<long> items, Func<long, long> operation, long testDivider, int testFailMonkey, int testSuccessMonkey)
{
Number = number;
_operation = operation;
@@ -23,15 +23,15 @@ public class Monkey
_testSuccessMonkey = testSuccessMonkey;
InspectionCount = 0;
_items = new Queue<int>(items);
_items = new Queue<long>(items);
}
public void AddItem(int item)
public void AddItem(long item)
{
_items.Enqueue(item);
}
public bool ThrowItem(IImmutableList<Monkey> monkeys)
public bool ThrowItem(IImmutableList<Monkey> monkeys, bool divideWorry = true)
{
// Return false if there's no item to throw
if (_items.Count < 1)
@@ -49,7 +49,14 @@ public class Monkey
var newValue = _operation(item);
// Divide worry level by 3 before test
newValue = newValue / 3;
if (divideWorry)
{
newValue = newValue / 3;
}
// Even using this simplification, it's still needed to use longs because
// they sometime overflow before being simplified in part 2
newValue = newValue % (2*3*5*7*11*13*17*19);
// Test is a success
if (newValue % _testDivider == 0)
@@ -93,7 +100,23 @@ public class Day11 : Day
public override void RunPart2()
{
throw new NotImplementedException();
const int roundsCount = 10_000;
var monkeys = ParseMonkeys();
// Do 10 000 rounds
for (int round = 0; round < roundsCount; round++)
{
foreach (var monkey in monkeys)
{
// Throw items while there's some
while (monkey.ThrowItem(monkeys, false)) { }
}
}
var topMonkeys = monkeys.OrderByDescending(m => m.InspectionCount).Take(2).ToList();
AnsiConsole.MarkupLine($"[green]Monkey business: [yellow]{topMonkeys[0].InspectionCount * topMonkeys[1].InspectionCount}[/][/]");
}
private static IImmutableList<Monkey> ParseMonkeys()
@@ -113,13 +136,13 @@ public class Day11 : Day
// Monkey attributes
var number = int.Parse(numberLine[numberLine.LastIndexOf(' ')..^1]);
var items = itemsLine[(itemsLine.IndexOf(':') + 2)..].Split(", ").Select(int.Parse);
var items = itemsLine[(itemsLine.IndexOf(':') + 2)..].Split(", ").Select(long.Parse);
// Read operation
operationLine = operationLine[(operationLine.IndexOf('=') + 2)..];
int? rightOperand = operationLine.EndsWith("old") ? null : int.Parse(operationLine.Split('+', '*')[1].Trim());
long? rightOperand = operationLine.EndsWith("old") ? null : long.Parse(operationLine.Split('+', '*')[1].Trim());
Func<int, int> operation = operationLine.Contains('+') switch
Func<long, long> operation = operationLine.Contains('+') switch
{
true => rightOperand is null
? old => old + old
@@ -129,7 +152,7 @@ public class Day11 : Day
: old => old * (int)rightOperand
};
var testDivider = int.Parse(testDividerLine[testDividerLine.LastIndexOf(' ')..]);
var testDivider = long.Parse(testDividerLine[testDividerLine.LastIndexOf(' ')..]);
var testSuccessMonkey = int.Parse(testSuccessLine[testSuccessLine.LastIndexOf(' ')..]);
var testFailMonkey = int.Parse(testFailLine[testFailLine.LastIndexOf(' ')..]);