day-24.rb
# All blocks are identical save for parameter changes, let's use that to cut down constraint number
All blocks are identical save for parameter changes, let's use that to cut down constraint number
All blocks are identical save for parameter changes let ' s use that to cut down constraint number
def resolve_constraints_opt(goal)
    segments = input.chunk { |op,*_| op == 'inp' }.map(&:last).each_slice(2).to_a.map { |ops| ops.flatten(1) }
    parameters = segments.map { |segment| [segment[4][2], segment[5][2], segment[15][2]].map(&:to_i) }
    solver = Z3::Optimize.new
    digits = Array.new(14) { |n| Z3.Int("digit-#{n.to_s.rjust(2, '0')}") }
    digits.each { |digit| solver.assert (digit >= 1).& (digit <= 9) }
    input_arg = digits.reverse.each_with_index.map { |n,i| n*(10**i) }.reduce(&:+)
    solver.send goal, input_arg
    z = Z3.Int('z0')
    solver.assert z == 0
    parameters.each_with_index do |(q,r,n), i|
      w = digits[i]
      condition = z.mod(26) + r == w
      z = Z3::IfThenElse(z.mod(26) + r == w, z / q, z * 26 / q + w + n)
    end
    solver.assert z == 0
    solver.satisfiable?
    solver.model.model_eval(input_arg).to_i
  end
def resolve_constraints_opt ( goal ) segments = input . chunk { | op , * _ | op == 'inp' } . map ( & :last ) . each_slice ( 2 ) . to_a . map { | ops | ops . flatten ( 1 ) } parameters = segments . map { | segment | [ segment [ 4 ] [ 2 ] , segment [ 5 ] [ 2 ] , segment [ 15 ] [ 2 ] ] . map ( & :to_i ) } solver = Z3 :: Optimize . new digits = Array . new ( 14 ) { | n | Z3 . Int ( "digit-#{n.to_s.rjust(2, '0')}" ) } digits . each { | digit | solver . assert ( digit >= 1 ) . & ( digit <= 9 ) } input_arg = digits . reverse . each_with_index . map { | n , i | n * ( 10 ** i ) } . reduce ( & :+ ) solver . send goal , input_arg z = Z3 . Int ( 'z0' ) solver . assert z == 0 parameters . each_with_index do | ( q , r , n ) , i | w = digits [ i ] condition = z . mod ( 26 ) + r == w z = Z3 :: IfThenElse ( z . mod ( 26 ) + r == w , z / q , z * 26 / q + w + n ) end solver . assert z == 0 solver . satisfiable? solver . model . model_eval ( input_arg ) . to_i end
All blocks are identical save for parameter changes, let's use that to cut down constraint number
All blocks are identical save for parameter changes let ' s use that to cut down constraint number
goal
<not_specific>