Learning Python

D

Dr. Pastor

Attempting to learn Python; I constructed the module
listed below. I would like to make it shorter, faster,
more "Python like". (Windows XP, Pro.)
Many thanks for any advice!
....

#-------------------------------------------------------------------------------
# Name: SendMoreMoney.py
# Purpose: A solution to the SEND+MORE=MONEY puzzle.
#
# Author: Dr. Pastor
#
# Copyright: (c) Dr. Pastor 2006

#-------------------------------------------------------------------------------
#!/usr/bin/env python

#
# The solution for the puzzle of
# SEND
# +MORE
# -----
# MONEY
#

def perm(items, n=None):
if n is None:
n = len(items)
for i in range(len(items)):
v = items[i:i+1]
if n == 1:
yield v
else:
rest = items[:i] + items[i+1:]
for p in perm(rest, n-1):
yield v + p

def comb(items, n=None):
if n is None:
n = len(items)
for i in range(len(items)):
v = items[i:i+1]
if n == 1:
yield v
else:
rest = items[i+1:]
for c in comb(rest, n-1):
yield v + c
#
# S E N D M O R Y
# ['0','1','2','3','4','5','6','7','8','9']
#
print
print "Selections of 8 items from 10 then the permutation of them."
print
b=0
for s in comb([0,1,2,3,4,5,6,7,8,9],8):
for a in perm(s,None):
if (a[4]*1000+a[5]*100+a[2]*10+a[1])*10+a[7] == \
(a[0]+a[4])*1000+(a[1]+a[5])*100+(a[2]+a[6])*10+(a[3]+a[1]):
b += 1
print ' SEND', ' ',a[0],a[1],a[2],a[3]
print ' MORE', ' ',a[4],a[5],a[6],a[1]
print ' ----', ' ---------'
print 'MONEY', '',a[4],a[5],a[2],a[1],a[7]
print
print "There are ", b, " solutions."
print
....
 
G

Gabriel Genellina

At said:
Attempting to learn Python; I constructed the module
listed below. I would like to make it shorter, faster,
more "Python like". (Windows XP, Pro.)
Many thanks for any advice!
...

#-------------------------------------------------------------------------------
# Name: SendMoreMoney.py
# Purpose: A solution to the SEND+MORE=MONEY puzzle.
#
# Author: Dr. Pastor
#
# Copyright: (c) Dr. Pastor 2006

#-------------------------------------------------------------------------------
#!/usr/bin/env python

This line is not used on Windows, but if you want to include it, must
be the very first line on the script.

#
# The solution for the puzzle of
# SEND
# +MORE
# -----
# MONEY
#

def perm(items, n=None):
if n is None:
n = len(items)
for i in range(len(items)):
v = items[i:i+1]

I would use v = [items] but that's a matter of taste...
if n == 1:
yield v
else:
rest = items[:i] + items[i+1:]
for p in perm(rest, n-1):
yield v + p

def comb(items, n=None):
if n is None:
n = len(items)
for i in range(len(items)):
v = items[i:i+1]

Same as above.
if n == 1:
yield v
else:
rest = items[i+1:]
for c in comb(rest, n-1):
yield v + c
#
# S E N D M O R Y
# ['0','1','2','3','4','5','6','7','8','9']
#
print
print "Selections of 8 items from 10 then the permutation of them."
print
b=0
for s in comb([0,1,2,3,4,5,6,7,8,9],8):
for a in perm(s,None):
if (a[4]*1000+a[5]*100+a[2]*10+a[1])*10+a[7] == \
(a[0]+a[4])*1000+(a[1]+a[5])*100+(a[2]+a[6])*10+(a[3]+a[1]):

Backslash as continuation is a bit problematic (add an empty space
after it and it's broken...) so it's better to add an open parens;
continuation is implicit until the last parens is closed:

if (a[4]*10000+a[5]*1000+a[2]*100+a[1]*10+a[7] ==
(a[0]+a[4])*1000+(a[1]+a[5])*100+(a[2]+a[6])*10+(a[3]+a[1])):

If speed is not the most important thing, you could assign names to
the 8 items:

S, E, N, D, M, O, R, Y = a
if poly(10, M,O,N,E,Y) == poly(10, S,E,N,D) + poly(10, M,O,R,E):

which is infinitely more legible (and a bit compact, too).
(poly is left as an exercise: def poly(x, *args): )

And a,b,s are too short names...



Gabriel Genellina
Softlab SRL





__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas
 
B

Ben Finney

Dr. Pastor said:
#-------------------------------------------------------------------------------
# Name: SendMoreMoney.py
# Purpose: A solution to the SEND+MORE=MONEY puzzle.
#
# Author: Dr. Pastor
#
# Copyright: (c) Dr. Pastor 2006

#-------------------------------------------------------------------------------
#!/usr/bin/env python

This line, to be at all meaningful, must be the first line in the
file, with no leading spaces.

said:
#
# The solution for the puzzle of
# SEND
# +MORE
# -----
# MONEY
#

Somewhat more useful than a comment block to describe your module is a
"doc string" for the module:

<URL:http://www.python.org/dev/peps/pep-0257/>

You will also thank yourself for writing descriptive doc strings for
each function and class (preferably as soon as you begin writing the
definition, so you don't need to remember to come back later and do
them).
 
D

Dennis Lee Bieber

Attempting to learn Python; I constructed the module
listed below. I would like to make it shorter, faster,
more "Python like". (Windows XP, Pro.)
Many thanks for any advice!
Unfortunately, you have chosen an example problem for which a
programmed solver is not easy. One either falls back on the brute force
method -- as your code does -- or one must become skilled in the realms
of symbol manipulation combined with rule-based artificial intelligence.

Consider: a human solving the

send
+more
--------
money

"puzzle" is expected to assume it is using base-10 (decimal) arithmetic.
Furthermore, by the rules of decimal arithmetic, the worst case for the
addition of the least significant digit is "9+9" yielding a carry of "1"
and a resultant LSD of 8. For all other digit positions, the worst case
becomes "9+9+1", which still yields a carry of "1", but a resultant of
9.

One then recognizes that the "send+more=>money" represents a
carry from the fourth place to the fifth AND that such a carry can only
be the value "1". One thereby concludes that "m" => "1", giving:

send
+1ore
--------
1oney

Going further, given "1+x+c", where "c" is a possible carry
(that is 0 or 1), the only values for "s" which still result in a carry
are "8" with a carry or "9" with or without a carry.

But… "1+9+1" => carry with resultant of "1", and since "m" is
already "1", "o" CANNOT be "1". That leaves us with only "1+9+0" and
"1+8+1", both giving a carry of "1" and a resultant of "0". "o" is "0",
therefore, and the puzzle looks like:

send
+10re
--------
10ney

"e+0+c", to result in a carry, requires "e" to be "9" and "c" to
be a carry "1". But "9+0+1" => carry "1" and resultant "0"… "o" is "0"
so "n" CANNOT be "0". From this, we conclude that "e" is not "9" AND
that there is no carry to be applied to "s". "s" must be "9". The puzzle
has now become:

9end
+10re
--------
10ney

Since "e+0" gives "n", we know that 1) there is a carry from
"n+r+c", and 2) "n" is "e+1". "n" is not "9", so the largest value "e"
can take on is "7". At this point we have:

"n = e+1"
"1e = n+r+c"

substituting

"1e = e+1+r+c" or
"10 = 1+r+c" or
"9 = r+c"

From which we conclude "r" must be "8" and "d+e" has a carry.
The puzzle is:

9end
+108e
--------
10ney

The unassigned values are 2, 3, 4, 5, 6, 7

The largest sum available is "6+7" giving "13"; the smallest sum
available that still produces a carry and does not conflict with
assigned values is "5+7" for "12". Either "d" or "e" must be a "7".
Since "e" is less than "n", it must be less than "7". This means "d"
must be "7"

9en7
+108e
---------
10ney

"e" can not be 6, as "n" is "e+1". So "e" must be "5" and "n"
must be "6"

9567
+1085
--------
1065y

so "y" must be "2"

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

Unfortunately, the only bit of reasoning that can be easily
coded is:

abcd
+wxyz
--------
Mnopq

IF len(abcd) = len(wxyz) AND len(abcd)+1 = len(Mnopq) THEN
M => 1

And you COULD initialize your brute force method with the same test.

--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top