[QUIZ] Verbal Arithmetic (#128)

Andreas Launila wrote:

Since we now have to start exploring the search space we make a guess
that e=4. Propagating the constraints once again with e given the domain
4 will directly result in a failure, so we backtrack and now know that
e!=4. With that information we redo the propagation and directly end up
at the solution with no need to explore any further.

I forgot a node in the middle there (since there are 4 nodes). The
complete search is:

1) Root: s=9, e=4..7, n=5..8, d=2..8, m=1, o=0, r=2..8, y=2..8
2) Tries e = 4: fails.
3) Knows e != 4: s=9, e=5..7, n=6..8, d=2..8, m=1, o=0, r=2..8, y=2..8
4) Tries e = 5: s=9, e=5, n=6, d=7, m=1, o=0, r=8, y=2 (success)

···

--
Andreas Launila

ohh I totally misunderstood the task here.. I thought the input would be send+more and my app should give money as answer trough calculation..

James Edward Gray II wrote:

···

On Jun 15, 2007, at 7:55 AM, anansi wrote:

I really don't get it :slight_smile: How did you figured out that 2 = y in your example?

Well, a non-clever way is to try an exhaustive search of each digit for each letter.

James Edward Gray II

--
greets

                     one must still have chaos in oneself to be able to give birth to a dancing star

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

anansi wrote, On 6/15/2007 8:10 AM:

ohh I totally misunderstood the task here.. I thought the input would be send+more and my app should give money as answer trough calculation..

For perhaps a reason to change the wording, that's what I thought as well until I read the explanation to anansi's question.

Sam

···

James Edward Gray II wrote:

On Jun 15, 2007, at 7:55 AM, anansi wrote:

I really don't get it :slight_smile: How did you figured out that 2 = y in your example?

Well, a non-clever way is to try an exhaustive search of each digit for each letter.

James Edward Gray II

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....

Thanks. There have been far more clever submissions though.

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

Good points.

James Edward Gray II

···

On Jun 19, 2007, at 9:30 AM, Eugene Kalenkovich wrote:

On Jun 18, 4:59 pm, James Edward Gray II <j...@grayproductions.net> > wrote:

Sorry for the confusion folks. You get both sides of the equation and are expected to fine the digit to represent each letter.

James Edward Gray II

···

On Jun 15, 2007, at 8:17 AM, Sammy Larbi wrote:

anansi wrote, On 6/15/2007 8:10 AM:

ohh I totally misunderstood the task here.. I thought the input would be send+more and my app should give money as answer trough calculation..

For perhaps a reason to change the wording, that's what I thought as well until I read the explanation to anansi's question.

Hmm maybe this helps to clarify (for emacs users) the problem is like
mpuzz :slight_smile: (mpuz?)

Robert

···

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

I hate these puzzles, but to clarify what you want to do:

send
+more

···

----------
money

using the key becomes: s: 9 e: 5 n: 6 d: 7 m: 1 o: 0 r: 8 y: 2

   9567
+ 1085
----------
10652

So your task is to find the key.

Jason

On 6/15/07, Robert Dober <robert.dober@gmail.com> wrote:

Hmm maybe this helps to clarify (for emacs users) the problem is like
mpuzz :slight_smile: (mpuz?)

Robert

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

Jason,

So your task is to find the key.

    Just think of these as a cryptogram with numbers instead of letters.

    - Warren Brown