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
g: 3
r: 7
f: 8
and modified one corrects it to
b: 1
o: 0
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
···
On Jun 18, 4:59 pm, James Edward Gray II <j...@grayproductions.net> wrote:
a: 2
a: 2