Add day 11 code
This commit is contained in:
parent
efa81418eb
commit
8dda1b5ee2
96
day11.chpl
Normal file
96
day11.chpl
Normal 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
58
day11.cr
Normal 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
|
Loading…
Reference in New Issue
Block a user