[2022][ruby][21.x] use z3 for part two

pull/1/head
Alpha Chen 2 years ago
parent b62bf80b86
commit a3bded6091
Signed by: alpha
SSH Key Fingerprint: SHA256:3fOT8fiYQG/aK9ntivV3Bqtg8AYQ7q4nV6ZgihOA20g

@ -13,6 +13,27 @@ monkeys = ARGF.read.lines(chomp: true).to_h {|line| line.split(": ") }
sub_monkeys = monkeys.delete("root").split(" + ") sub_monkeys = monkeys.delete("root").split(" + ")
monkeys.delete("humn") monkeys.delete("humn")
require "z3"
solver = Z3::Solver.new
solver.assert Z3.Int(sub_monkeys[0]) == Z3.Int(sub_monkeys[1])
monkeys.each do |name, job|
a, op, b = job.split(" ")
if op.nil?
solver.assert Z3.Int(name) == a.to_i
else
a = a =~ /^\d+$/ ? a.to_i : Z3.Int(a)
b = b =~ /^\d+$/ ? b.to_i : Z3.Int(b)
solver.assert Z3.Int(name) == a.send(op, b)
end
end
fail unless solver.satisfiable?
p solver.model[Z3.Int("humn")]
exit
# original part two
monkeys.each do |name, body| monkeys.each do |name, body|
define_method(name) do define_method(name) do
eval(body) eval(body)
@ -53,8 +74,7 @@ def reverse(target, tree)
case tree case tree
in :humn in :humn
return target return target
in [op, Integer, b] in [op, Integer => a, b]
a = tree.fetch(1)
case op case op
when ?* then target /= a when ?* then target /= a
when ?+ then target -= a when ?+ then target -= a
@ -62,8 +82,7 @@ def reverse(target, tree)
else fail tree.inspect else fail tree.inspect
end end
tree = b tree = b
in [op, a, Integer] in [op, a, Integer => b]
b = tree.fetch(2)
case op case op
when ?- then target += b when ?- then target += b
when ?/ then target *= b when ?/ then target *= b

Loading…
Cancel
Save