From: Eugene Kalenkovich Date: 2007-06-19T23:30:05+09:00 Subject: Re: [QUIZ] Verbal Arithmetic (#128) On Jun 18, 4:59 pm, James Edward Gray II wrote: >> It's of the dumb-brute-force-slow-as-hell variety: > Mine was too: > #!/usr/bin/env ruby -wKU > > EQUATION = ARGV.shift.to_s.downcase.sub("=", "==") > LETTERS = EQUATION.scan(/[a-z]/).uniq > CHOICES = LETTERS.inject(Hash.new) do |all, letter| > all.merge(letter => EQUATION =~ /\b#{letter}/ ? 1..9 : 0..9) > end > > def search(choices, mapping = Hash.new) > if choices.empty? > letters, digits = mapping.to_a.flatten.partition { |e| e.is_a? > String } > return mapping if eval(EQUATION.tr(letters.join, digits.join)) > else > new_choices = choices.dup > letter = new_choices.keys.first > digits = new_choices.delete(letter).to_a - mapping.values > > digits.each do |choice| > if result = search(new_choices, mapping.merge(letter => choice)) > return result > end > end > > return nil > end > end > > if solution = search(CHOICES) > LETTERS.each { |letter| puts "#{letter}: #{solution[letter]}" } > else > puts "No solution found." > end > > __END__ > I really like it - your solution covers any type of expression :). Perhaps some preprocessing of CHOICES can save the performance.... The only thing, assuming that all examples are always integers, I'd add .sub(/([a-z])([^a-z])/,'\1.0\2') to EQUATION to cover examples with division (to drop the assumption, before adding .0 one can regexp it for '.'s) for 'boaogr/foo=bar' (arbitrary example) your code gives b: 1 o: 0 a: 2 g: 3 r: 7 f: 8 and modified one corrects it to b: 1 o: 0 a: 2 g: 3 r: 7 f: 8 I can expect that this modification may break on rounding errors, but in this task domain I do not think it will