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