You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
advent-of-code/2022/ruby/test_day_11.rb

62 lines
1.5 KiB

require "bundler/setup"
require "minitest/autorun"
require "parslet"
Monkey = Struct.new(:id, :items, :operation, :test, :t, :f) do
def throw_to(item)
(item % test).zero? ? t : f
end
end
class MonkeyParser < Parslet::Parser
rule(:num) { match("[0-9]").repeat.as(:num) }
rule(:space) { match("\\s").repeat }
rule(:newline) { str("\n") }
rule(:monkey) {
space >> str("Monkey ") >> num.as(:id) >> str(":") >>
space >> str("Starting items: ") >> ( num >> ( str(", ") >> num ).repeat ).as(:items) >>
space >> str("Operation: new = ") >> (newline.absent? >> any).repeat.as(:op) >>
space >> str("Test: divisible by ") >> num.as(:test) >>
space >> str("If true: throw to monkey ") >> num.as(:true) >>
space >> str("If false: throw to monkey ") >> num.as(:false) >>
space
}
rule(:monkeys) { monkey.repeat }
root(:monkeys)
end
class MonkeyTransform < Parslet::Transform
rule(num: simple(:x)) { x.to_i }
rule(
id: simple(:id),
items: sequence(:items),
op: simple(:op),
test: simple(:test),
true: simple(:t),
false: simple(:f),
) {
Monkey.new(id, items, op, test, t, f)
}
end
class TestDay11 < Minitest::Test
def test_day_11
tree = MonkeyParser.new.parse(<<~MONKEY)
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
monkeys = MonkeyTransform.new.apply(tree)
assert_equal [Monkey.new(0, [79, 98], "old * 19", 23, 2, 3)], monkeys
end
end