diff --git a/advanced-iterators.html b/advanced-iterators.html index 5cb4f44..25e3ee7 100644 --- a/advanced-iterators.html +++ b/advanced-iterators.html @@ -17,11 +17,289 @@ body{counter-reset:h1 6}
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, in+ ++AssertionError
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, in+ ++StopIteration
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 ℳark Pilgrim - diff --git a/examples/alphametics.py b/examples/alphametics.py index dd64677..2476eaa 100644 --- a/examples/alphametics.py +++ b/examples/alphametics.py @@ -8,18 +8,20 @@ import re import itertools def solve(puzzle): - words = re.findall('[A-Z]+', puzzle) - unique_characters = set(''.join(words)) + words = re.findall('[A-Z]+', puzzle.upper()) + unique_characters = {c for c in ''.join(words)} assert len(unique_characters) <= 10 - first_letters = set(word[0] for word in words) + first_letters = {word[0] for word in words} n = len(first_letters) sorted_characters = ''.join(first_letters) + \ ''.join(unique_characters - first_letters) - characters = tuple(map(ord, sorted_characters)) - digits = tuple(map(ord, '0123456789')) + 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]: + print(guess) + return equation = puzzle.translate(dict(zip(characters, guess))) if eval(equation): return equation