diff --git a/input/11.txt b/input/11.txt new file mode 100644 index 0000000..6085097 --- /dev/null +++ b/input/11.txt @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 89, 95, 92, 64, 87, 68 + Operation: new = old * 11 + Test: divisible by 2 + If true: throw to monkey 7 + If false: throw to monkey 4 + +Monkey 1: + Starting items: 87, 67 + Operation: new = old + 1 + Test: divisible by 13 + If true: throw to monkey 3 + If false: throw to monkey 6 + +Monkey 2: + Starting items: 95, 79, 92, 82, 60 + Operation: new = old + 6 + Test: divisible by 3 + If true: throw to monkey 1 + If false: throw to monkey 6 + +Monkey 3: + Starting items: 67, 97, 56 + Operation: new = old * old + Test: divisible by 17 + If true: throw to monkey 7 + If false: throw to monkey 0 + +Monkey 4: + Starting items: 80, 68, 87, 94, 61, 59, 50, 68 + Operation: new = old * 7 + Test: divisible by 19 + If true: throw to monkey 5 + If false: throw to monkey 2 + +Monkey 5: + Starting items: 73, 51, 76, 59 + Operation: new = old + 8 + Test: divisible by 7 + If true: throw to monkey 2 + If false: throw to monkey 1 + +Monkey 6: + Starting items: 92 + Operation: new = old + 5 + Test: divisible by 11 + If true: throw to monkey 3 + If false: throw to monkey 0 + +Monkey 7: + Starting items: 99, 76, 78, 76, 79, 90, 89 + Operation: new = old + 7 + Test: divisible by 5 + If true: throw to monkey 4 + If false: throw to monkey 5 diff --git a/input/11sample.txt b/input/11sample.txt new file mode 100644 index 0000000..c04eddb --- /dev/null +++ b/input/11sample.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/s11a.d b/src/s11a.d new file mode 100644 index 0000000..0e0f5bd --- /dev/null +++ b/src/s11a.d @@ -0,0 +1,57 @@ +module s11a; +import util; + +void main() { + Monkey[] monkeys = readText("input/11.txt").strip.splitter("\n\n") + .map!(parseMonkey).array; + + for (int i = 0; i < 20; i++) { + for (int mId = 0; mId < monkeys.length; mId++) { + Monkey* m = &monkeys[mId]; + while (m.items.length > 0) { + int item = m.items[0]; + m.items = m.items.remove(0); + + char op = m.operation[0]; + string argS = m.operation[1]; + int arg = argS == "old" ? item : argS.to!int; + int newValue; + if (op == '+') newValue = item + arg; + if (op == '*') newValue = item * arg; + + newValue /= 3; + + if (newValue % m.testDivisor == 0) { + monkeys[m.testTrueMonkeyId].items ~= newValue; + } else { + monkeys[m.testFalseMonkeyId].items ~= newValue; + } + m.inspections++; + } + } + } + + int[] topValues = monkeys.map!(m => m.inspections).array.topN!"a > b"(2); + int monkeyBusiness = reduce!"a * b"(1, topValues); + writeln(monkeyBusiness); +} + +struct Monkey { + int[] items; + Tuple!(char, string) operation; + int testDivisor; + int testTrueMonkeyId; + int testFalseMonkeyId; + int inspections; +} + +Monkey parseMonkey(string s) { + string[] lines = s.splitter("\n").array; + Monkey m; + m.items = lines[1][18..$].splitter(", ").map!(s => s.to!int).array; + m.operation = Tuple!(char, string)(lines[2][23], lines[2][25..$]); + m.testDivisor = lines[3][21..$].to!int; + m.testTrueMonkeyId = lines[4][29..$].to!int; + m.testFalseMonkeyId = lines[5][30..$].to!int; + return m; +} diff --git a/src/s11b.d b/src/s11b.d new file mode 100644 index 0000000..3f6779f --- /dev/null +++ b/src/s11b.d @@ -0,0 +1,65 @@ +module s11a; +import util; + +import std.bigint; + +void main() { + Monkey[] monkeys = readText("input/11sample.txt").strip.splitter("\n\n") + .map!(parseMonkey).array; + + for (int i = 0; i < 10_000; i++) { + writefln!"Round %d"(i + 1); + for (int mId = 0; mId < monkeys.length; mId++) { + Monkey* m = &monkeys[mId]; + while (m.items.length > 0) { + BigInt item = m.items[0]; + m.items = m.items.remove(0); + + char op = m.operation[0]; + string argS = m.operation[1]; + BigInt arg = argS == "old" ? item : argS.to!BigInt; + BigInt newValue; + if (op == '+') newValue = item + arg; + if (op == '*') newValue = item * arg; + + if (newValue % m.testDivisor == 0) { + monkeys[m.testTrueMonkeyId].items ~= newValue; + } else { + monkeys[m.testFalseMonkeyId].items ~= newValue; + } + m.inspections++; + } + } + if ((i + 1) % 1000 == 0) { + writefln!"== After round %d =="(i + 1); + for (int mId = 0; mId < monkeys.length; mId++) { + writefln!"Monkey %d inspected items %d times."(mId, monkeys[mId].inspections); + writeln(monkeys[mId].items); + } + } + } + + ulong[] topValues = monkeys.map!(m => m.inspections).array.topN!"a > b"(2UL); + ulong monkeyBusiness = reduce!"a * b"(1UL, topValues); + writeln(monkeyBusiness); +} + +struct Monkey { + BigInt[] items; + Tuple!(char, string) operation; + int testDivisor; + int testTrueMonkeyId; + int testFalseMonkeyId; + ulong inspections; +} + +Monkey parseMonkey(string s) { + string[] lines = s.splitter("\n").array; + Monkey m; + m.items = lines[1][18..$].splitter(", ").map!(s => s.to!BigInt).array; + m.operation = Tuple!(char, string)(lines[2][23], lines[2][25..$]); + m.testDivisor = lines[3][21..$].to!int; + m.testTrueMonkeyId = lines[4][29..$].to!int; + m.testFalseMonkeyId = lines[5][30..$].to!int; + return m; +} diff --git a/src/util.d b/src/util.d index a9a070f..9d544a9 100644 --- a/src/util.d +++ b/src/util.d @@ -13,6 +13,7 @@ public import std.uni; public import std.array; public import std.format; public import std.math; +public import std.typecons; /** * Simple set implementation since the stdlib doesn't really have a good one.