parent
7ced4db4a4
commit
6fb92a59ab
@ -0,0 +1,81 @@
|
|||||||
|
monkeys = ARGF.read.lines(chomp: true).to_h {|line| line.split(": ") }
|
||||||
|
|
||||||
|
# part one
|
||||||
|
# monkeys.each do |name, body|
|
||||||
|
# define_method(name) do
|
||||||
|
# eval(body)
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
# p root
|
||||||
|
|
||||||
|
# part two
|
||||||
|
sub_monkeys = monkeys.delete("root").split(" + ")
|
||||||
|
monkeys.delete("humn")
|
||||||
|
|
||||||
|
monkeys.each do |name, body|
|
||||||
|
define_method(name) do
|
||||||
|
eval(body)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
target, unknown = sub_monkeys.partition { eval(_1) rescue nil}.map(&:first)
|
||||||
|
target = eval(target)
|
||||||
|
|
||||||
|
monkeys = monkeys.to_h {|monkey, job|
|
||||||
|
a, op, b = job.split(" ")
|
||||||
|
[monkey, { op:, a:, b: }]
|
||||||
|
}
|
||||||
|
monkeys["humn"] = { op: :humn }
|
||||||
|
|
||||||
|
def apply(monkeys, monkey)
|
||||||
|
job = monkeys.fetch(monkey)
|
||||||
|
case op = job.fetch(:op)
|
||||||
|
when nil
|
||||||
|
job.fetch(:a).to_i
|
||||||
|
when :humn
|
||||||
|
:humn
|
||||||
|
else
|
||||||
|
a = apply(monkeys, job.fetch(:a))
|
||||||
|
b = apply(monkeys, job.fetch(:b))
|
||||||
|
if a.is_a?(Integer) && b.is_a?(Integer)
|
||||||
|
eval([a, op, b].join(" "))
|
||||||
|
else
|
||||||
|
[job.fetch(:op), a, b]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tree = apply(monkeys, unknown)
|
||||||
|
|
||||||
|
def reverse(target, tree)
|
||||||
|
loop do
|
||||||
|
case tree
|
||||||
|
in :humn
|
||||||
|
return target
|
||||||
|
in [op, Integer, b]
|
||||||
|
a = tree.fetch(1)
|
||||||
|
case op
|
||||||
|
when ?* then target /= a
|
||||||
|
when ?+ then target -= a
|
||||||
|
when ?- then target = a - target
|
||||||
|
else fail tree.inspect
|
||||||
|
end
|
||||||
|
tree = b
|
||||||
|
in [op, a, Integer]
|
||||||
|
b = tree.fetch(2)
|
||||||
|
case op
|
||||||
|
when ?- then target += b
|
||||||
|
when ?/ then target *= b
|
||||||
|
when ?* then target /= b
|
||||||
|
when ?+ then target -= b
|
||||||
|
else fail tree.inspect
|
||||||
|
end
|
||||||
|
tree = a
|
||||||
|
else
|
||||||
|
fail tree.inspect
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
p reverse(target, tree)
|
Loading…
Reference in new issue