Add day 11 code

This commit is contained in:
Danila Fedorin 2022-12-12 11:38:59 -08:00
parent efa81418eb
commit 8dda1b5ee2
2 changed files with 154 additions and 0 deletions

96
day11.chpl Normal file
View File

@ -0,0 +1,96 @@
use IO, List;
var modulus = 1;
record DivByThree {
var underlying: int;
operator +(lhs: DivByThree, rhs: DivByThree) {
return new DivByThree((lhs.underlying + rhs.underlying) / 3);
}
operator *(lhs: DivByThree, rhs: DivByThree) {
return new DivByThree((lhs.underlying * rhs.underlying) / 3);
}
proc divBy(x: int) return underlying % x == 0;
}
record Modulo {
var underlying: int;
operator +(lhs: Modulo, rhs: Modulo) {
return new Modulo((lhs.underlying + rhs.underlying) % modulus);
}
operator *(lhs: Modulo, rhs: Modulo) {
return new Modulo((lhs.underlying * rhs.underlying) % modulus);
}
proc divBy(x: int) return underlying % x == 0;
}
config type numtype = DivByThree;
config const steps = 20;
class Op {
proc apply(x: ?t) return x;
}
class SquareOp : Op {
override proc apply(x) return x * x;
}
class AddOp : Op {
var toAdd;
override proc apply(x) return x + toAdd;
}
class MulOp : Op {
var toMul;
override proc apply(x) return x * toMul;
}
proc parse(op: string): owned Op {
if op == "old * old" then return new SquareOp();
if op.startsWith("old + ") then return new AddOp(new numtype(op[6..] : int));
return new MulOp(new numtype(op[6..] : int));
}
record Monkey {
var op : owned Op;
var divBy, ifTrue, ifFalse : int;
var items: list(numtype);
var count: int = 0;
iter tossItems() {
while !items.isEmpty() {
var item = items.pop(0);
var changed = op.apply(item);
var nextIdx = if changed.divBy(divBy) then ifTrue else ifFalse;
count += 1;
yield (changed, nextIdx);
}
}
}
var monkeys = new list(Monkey);
var line: string;
while readLine(line) {
proc toNum(x: string) return new numtype(x : int);
readLine(line, stripNewline=true);
var items = new list(toNum(line[" Starting items: ".size..].split(", ")));
readLine(line, stripNewline=true);
var op = parse(line[" Operation: new = ".size..]);
var divBy, ifTrue, ifFalse: int;
readf(" Test: divisible by %i\n", divBy);
readf(" If true: throw to monkey %i\n", ifTrue);
readf(" If false: throw to monkey %i\n", ifFalse);
monkeys.append(new Monkey(op, divBy, ifTrue, ifFalse, items));
modulus *= divBy;
if (!readln()) then break;
}
for 1..steps {
for monkey in monkeys {
for (item, nextIdx) in monkey.tossItems() {
monkeys[nextIdx].items.append(item);
}
}
}
writeln(monkeys.these().count);

58
day11.cr Normal file
View File

@ -0,0 +1,58 @@
require "advent"
require "big"
class Monkey
property items : Array(Int64)
property op : String
property divBy : Int64
property ifTrue : Int64
property ifFalse : Int64
def initialize(@items, @op, @divBy, @ifTrue, @ifFalse)
end
end
INSTS = {
"*" => ->(x: Int64, y: Int64) { x * y },
"+" => ->(x: Int64, y: Int64) { x + y }
}
def execute(inst, old, mod)
inst = inst.gsub("old", old.to_s);
l, op, r = inst.split(" ")
l = l.to_i64 % mod
r = r.to_i64 % mod
INSTS[op].call(l,r)
end
monkeys = [] of Monkey
input(2022, 11).split("\n\n").each do |it|
it = it.lines
items = it[1].split(": ")[1].split(", ").map(&.to_i64).reverse
op = it[2].split("Operation: new = ")[1]
divBy = it[3].split("Test: divisible by ")[1].to_i64
ifTrue = it[4].split(" If true: throw to monkey ")[1].to_i64
ifFalse = it[5].split(" If false: throw to monkey ")[1].to_i64
monkeys << Monkey.new(items, op, divBy, ifTrue, ifFalse)
end
counts = [0] * monkeys.size
modulus = monkeys.map(&.divBy).product
10000.times do
monkeys.each_with_index do |m, i|
while !m.items.empty?
counts[i] += 1
item = m.items.pop
item = execute(m.op, item, modulus)
item = item % modulus
if item % m.divBy == 0
monkeys[m.ifTrue].items.insert(0, item)
else
monkeys[m.ifFalse].items.insert(0, item)
end
end
end
end
counts.sort!
puts counts[-1].to_big_i * counts[-2].to_big_i