On Jun 18, 4:59 pm, James Edward Gray II <j... / grayproductions.net>
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