You are here: Home ‣ Dive Into Python 3 ‣
❝ My ambition is to live to see all of physics reduced to a formula so elegant and simple that it will fit easily on the front of a t-shirt. ❞
— Leon Lederman
FIXME
import re
import itertools
def solve(puzzle):
words = re.findall('[A-Z]+', puzzle.upper())
unique_characters = {c for c in ''.join(words)}
assert len(unique_characters) <= 10
first_letters = {word[0] for word in words}
n = len(first_letters)
sorted_characters = ''.join(first_letters) + \
''.join(unique_characters - first_letters)
characters = tuple(ord(c) for c in sorted_characters)
digits = tuple(ord(c) for c in '0123456789')
zero = digits[0]
for guess in itertools.permutations(digits, len(characters)):
if zero not in guess[:n]:
equation = puzzle.translate(dict(zip(characters, guess)))
if eval(equation):
return equation
if __name__ == '__main__':
import sys
for puzzle in sys.argv[1:]:
print(puzzle)
solution = solve(puzzle)
if solution:
print(solution)
you@localhost:~$ python3 alphametics.py "SEND + MORE == MONEY" SEND + MORE == MONEY 9567 + 1085 == 10652 you@localhost:~$ python3 alphametics.py "I + LOVE + YOU == DORA" I + LOVE + YOU == DORA 1 + 2784 + 975 == 3760
FIXME
>>> import re
>>> re.findall('[A-Z]+', 'SEND + MORE == MONEY')
['SEND', 'MORE', 'MONEY']
FIXME
>>> a_list = ['a', 'c', 'b', 'a', 'd', 'b']
>>> {c for c in a_list}
{'a', 'c', 'b', 'd'}
>>> a_string = 'EAST IS EAST'
>>> {c for c in a_string}
{'A', ' ', 'E', 'I', 'S', 'T'}
>>> words = ['SEND', 'MORE', 'MONEY']
>>> ''.join(words)
'SENDMOREMONEY'
>>> {c for c in ''.join(words)}
{'E', 'D', 'M', 'O', 'N', 'S', 'R', 'Y'}
FIXME
FIXME
>>> assert 1 + 1 = 2 >>> assert 1 + 1 = 3 Traceback (most recent call last): File "<stdin>", line 1, inAssertionError
FIXME
assert len(unique_characters) <= 10
…is equivalent to…
if len(unique_characters) > 10:
raise AssertionError
FIXME
>>> unique_characters = {'E', 'D', 'M', 'O', 'N', 'S', 'R', 'Y'}
>>> gen = (ord(c) for c in unique_characters)
>>> gen
<generator object <genexpr> at 0x00BADC10>
>>> next(gen)
69
>>> next(gen)
68
>>> tuple(ord(c) for c in unique_characters)
(69, 68, 77, 79, 78, 83, 82, 89)
FIXME
FIXME what are permutations?
>>> import itertools >>> perms = itertools.permutations([1, 2, 3], 2) >>> next(perms) (1, 2) >>> next(perms) (1, 3) >>> next(perms) (2, 1) >>> next(perms) (2, 3) >>> next(perms) (3, 1) >>> next(perms) (3, 2) >>> next(perms) Traceback (most recent call last): File "<stdin>", line 1, inStopIteration
FIXME
>>> import itertools
>>> perms = itertools.permutations('ABC', 3)
>>> next(perms)
('A', 'B', 'C')
>>> next(perms)
('A', 'C', 'B')
>>> next(perms)
('B', 'A', 'C')
>>> next(perms)
('B', 'C', 'A')
>>> next(perms)
('C', 'A', 'B')
>>> next(perms)
('C', 'B', 'A')
>>> next(perms)
Traceback (most recent call last):
File "<stdin>", line 1, in
StopIteration
>>> list(itertools.permutations('ABC', 3))
[('A', 'B', 'C'), ('A', 'C', 'B'),
('B', 'A', 'C'), ('B', 'C', 'A'),
('C', 'A', 'B'), ('C', 'B', 'A')]
FIXME
itertools Module
>>> import itertools
>>> list(itertools.product('ABC', '123'))
[('A', '1'), ('A', '2'), ('A', '3'),
('B', '1'), ('B', '2'), ('B', '3'),
('C', '1'), ('C', '2'), ('C', '3')]
>>> list(itertools.combinations('ABC', 2))
[('A', 'B'), ('A', 'C'), ('B', 'C')]
FIXME
>>> names = list(open('examples/favorite-people.txt'))
>>> names
['Dora\n', 'Ethan\n', 'Wesley\n', 'John\n', 'Anne\n',
'Mike\n', 'Chris\n', 'Sarah\n', 'Alex\n', 'Lizzie\n']
>>> names = [name[:-1] for name in names]
>>> names
['Dora', 'Ethan', 'Wesley', 'John', 'Anne',
'Mike', 'Chris', 'Sarah', 'Alex', 'Lizzie']
>>> names = sorted(names)
>>> names
['Alex', 'Anne', 'Chris', 'Dora', 'Ethan',
'John', 'Lizzie', 'Mike', 'Sarah', 'Wesley']
>>> names = sorted(names, key=len)
>>> names
['Alex', 'Anne', 'Dora', 'John', 'Mike',
'Chris', 'Ethan', 'Sarah', 'Lizzie', 'Wesley']
>>> import itertools
>>> groups = itertools.groupby(names, len)
>>> groups
<itertools.groupby object at 0x00BB20C0>
>>> list(groups)
[(4, <itertools._grouper object at 0x00BA8BF0>),
(5, <itertools._grouper object at 0x00BB4050>),
(6, <itertools._grouper object at 0x00BB4030>)]
>>> groups = itertools.groupby(names, len)
>>> for name_length, name_iter in groups:
... print('Names with {0:d} letters:'.format(name_length))
... for name in name_iter:
... print(name)
...
Names with 4 letters:
Alex
Anne
Dora
John
Mike
Names with 5 letters:
Chris
Ethan
Sarah
Names with 6 letters:
Lizzie
Wesley
FIXME
FIXME
>>> list(range(0, 3)) [0, 1, 2] >>> list(range(10, 13)) [10, 11, 12] >>> list(itertools.chain(range(0, 3), range(10, 13))) [0, 1, 2, 10, 11, 12] >>> list(zip(range(0, 3), range(10, 13))) [(0, 10), (1, 11), (2, 12)] >>> list(zip(range(0, 3), range(10, 14))) [(0, 10), (1, 11), (2, 12)] >>> list(itertools.zip_longest(range(0, 3), range(10, 14))) [(0, 10), (1, 11), (2, 12), (None, 13)]
FIXME
>>> characters = ('S', 'M', 'E', 'D', 'O', 'N', 'R', 'Y')
>>> guess = ('1', '2', '0', '3', '4', '5', '6', '7')
>>> tuple(zip(characters, guess))
(('S', '1'), ('M', '2'), ('E', '0'), ('D', '3'),
('O', '4'), ('N', '5'), ('R', '6'), ('Y', '7'))
>>> dict(zip(characters, guess))
{'E': '0', 'D': '3', 'M': '2', 'O': '4',
'N': '5', 'S': '1', 'R': '6', 'Y': '7'}
>>> characters = tuple(ord(c) for c in 'SMEDONRY')
>>> characters
(83, 77, 69, 68, 79, 78, 82, 89)
>>> digits = tuple(ord(c) for c in '0123456789')
>>> digits
(48, 49, 50, 51, 52, 53, 54, 55, 56, 57)
>>> guess = (49, 50, 48, 51, 52, 53, 54, 55)
>>> translation_table = dict(zip(characters, guess))
>>> translation_table
{68: 51, 69: 48, 77: 50, 78: 53, 79: 52, 82: 54, 83: 49, 89: 55}
>>> "SEND + MORE == MONEY".translate(translation_table)
'1053 + 2460 == 24507'
FIXME
>>> translation_table = {ord("A"): ord("O")}
>>> translation_table
{65: 79}
>>> 'MARK'.translate(translation_table)
'MORK'
FIXME
FIXME
FIXME
FIXME
© 2001–9 Mark Pilgrim