example/send_most_money.rb in gecoder-0.9.0 vs example/send_most_money.rb in gecoder-0.9.1

- old
+ new

@@ -1,58 +1,47 @@ require File.dirname(__FILE__) + '/example_helper' # Solves the cryptarithmetic send+most=money problem while maximizing the value # of "money". -class SendMoreMoney < Gecode::Model +class SendMostMoney + include Gecode::Mixin + attr :money def initialize # Set up the variables, 9 letters with domain 0..9. - s,e,n,d,m,o,s,t,y = @letters = int_var_array(9, 0..9) - @money = wrap_enum([m,o,n,e,y]) + s,e,n,d,m,o,s,t,y = letters_is_an int_var_array(9, 0..9) + # Express the quantity we are optimizing, in this case money. + # This utilises that any operand can be converted into a variable. + @money = equation_row(m,o,n,e,y).to_int_var # Set up the constraints. # The equation must hold. (equation_row(s, e, n, d) + equation_row(m, o, s, t)).must == - equation_row(m,o,n,e,y) + equation_row(m, o, n, e, y) # The initial letters may not be 0. s.must_not == 0 m.must_not == 0 # All letters must be assigned different digits. - @letters.must_be.distinct + letters.must_be.distinct # Set the branching. - branch_on @letters, :variable => :smallest_size, :value => :min + branch_on letters, :variable => :smallest_size, :value => :min end - def to_s - %w{s e n d m o s t y}.zip(@letters).map do |text, letter| - "#{text}: #{letter.value}" - end.join(', ') - end - private # A helper to make the linear equation a bit tidier. Takes a number of # variables and computes the linear combination as if the variable # were digits in a base 10 number. E.g. x,y,z becomes # 100*x + 10*y + z . def equation_row(*variables) - variables.to_number + variables.inject{ |result, variable| variable + result * 10 } end end -class Array - # Computes a number of the specified base using the array's elements as - # digits. - def to_number(base = 10) - inject{ |result, variable| variable + result * base } - end -end - -solution = SendMoreMoney.new.optimize! do |model, best_so_far| - model.money.to_number.must > best_so_far.money.values.to_number -end -puts solution.to_s -puts "money: #{solution.money.values.to_number}" +solution = SendMostMoney.new.maximize! :money +puts 's e n d m o s t y' +puts solution.letters.values.join(' ') +puts "money: #{solution.money.value}"