Skip to main content
Code Review

Return to Answer

fixed the overlooked renames
Source Link
def words(alphabet):
 yield ''
 for prefix in words(alphabet):
 for characterletter in alphabet:
 yield prefix + characterletter
from itertools import product, count, islice, chain
from timeit import repeat
from collections import deque
lib = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz°!"§$%&/()=ß ́`+#-.,><@€|^~–{[]}ÄÖÜäöü'
def Stefan_Pochmann(alphabet):
 yield ''
 for prefix in Stefan_Pochmann(alphabet):
 for characterletter in alphabet:
 yield prefix + characterletter
def Stefan_Pochmann_2(alphabet):
 yield ''
 for prefix in Stefan_Pochmann_2(alphabet):
 yield from map(prefix.__add__, alphabet)
def Ivo_Merchiers(lib):
 for length in count(0):
 for combination in product(lib, repeat=length):
 yield ''.join(combination)
def Ivo_Merchiers_2(lib):
 join = ''.join
 for length in count(0):
 for combination in product(lib, repeat=length):
 yield join(combination)
def Ivo_Merchiers_3(lib):
 for length in count(0):
 yield from map(''.join, product(lib, repeat=length))
def Ivo_Merchiers_chain(lib): # from Peilonrayz
 join = ''.join
 return chain.from_iterable(
 map(join, product(lib, repeat=length))
 for length in count(0)
 )
solutions = Stefan_Pochmann, Stefan_Pochmann_2, Ivo_Merchiers, Ivo_Merchiers_2, Ivo_Merchiers_3, Ivo_Merchiers_chain
for alphabet in lib, 'abc':
 print(alphabet)
 n = 10**7
 
 # Correctness
 sets = map(set, zip(*(words(alphabet) for words in solutions)))
 print(f'same first {n-1:,}:', all(len(s) == 1 for s in islice(sets, n - 1)))
 s = next(sets)
 print(f'same {n:,}th:', len(s) == 1, s)
 print()
 
 # Speed
 tss = [[] for _ in solutions]
 for _ in range(3):
 for words, ts in zip(solutions, tss):
 t = min(repeat(lambda: deque(islice(words(alphabet), n), 0), number=1))
 ts.append(t)
 for words, ts in zip(solutions, tss):
 print(*('%.2f' % t for t in ts), 'seconds ', words.__name__, sep=' ')
 print()
def words(alphabet):
 yield ''
 for prefix in words(alphabet):
 for character in alphabet:
 yield prefix + character
from itertools import product, count, islice, chain
from timeit import repeat
from collections import deque
lib = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz°!"§$%&/()=ß ́`+#-.,><@€|^~–{[]}ÄÖÜäöü'
def Stefan_Pochmann(alphabet):
 yield ''
 for prefix in Stefan_Pochmann(alphabet):
 for character in alphabet:
 yield prefix + character
def Stefan_Pochmann_2(alphabet):
 yield ''
 for prefix in Stefan_Pochmann_2(alphabet):
 yield from map(prefix.__add__, alphabet)
def Ivo_Merchiers(lib):
 for length in count(0):
 for combination in product(lib, repeat=length):
 yield ''.join(combination)
def Ivo_Merchiers_2(lib):
 join = ''.join
 for length in count(0):
 for combination in product(lib, repeat=length):
 yield join(combination)
def Ivo_Merchiers_3(lib):
 for length in count(0):
 yield from map(''.join, product(lib, repeat=length))
def Ivo_Merchiers_chain(lib): # from Peilonrayz
 join = ''.join
 return chain.from_iterable(
 map(join, product(lib, repeat=length))
 for length in count(0)
 )
solutions = Stefan_Pochmann, Stefan_Pochmann_2, Ivo_Merchiers, Ivo_Merchiers_2, Ivo_Merchiers_3, Ivo_Merchiers_chain
for alphabet in lib, 'abc':
 print(alphabet)
 n = 10**7
 
 # Correctness
 sets = map(set, zip(*(words(alphabet) for words in solutions)))
 print(f'same first {n-1:,}:', all(len(s) == 1 for s in islice(sets, n - 1)))
 s = next(sets)
 print(f'same {n:,}th:', len(s) == 1, s)
 print()
 
 # Speed
 tss = [[] for _ in solutions]
 for _ in range(3):
 for words, ts in zip(solutions, tss):
 t = min(repeat(lambda: deque(islice(words(alphabet), n), 0), number=1))
 ts.append(t)
 for words, ts in zip(solutions, tss):
 print(*('%.2f' % t for t in ts), 'seconds ', words.__name__, sep=' ')
 print()
def words(alphabet):
 yield ''
 for prefix in words(alphabet):
 for letter in alphabet:
 yield prefix + letter
from itertools import product, count, islice, chain
from timeit import repeat
from collections import deque
lib = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz°!"§$%&/()=ß ́`+#-.,><@€|^~–{[]}ÄÖÜäöü'
def Stefan_Pochmann(alphabet):
 yield ''
 for prefix in Stefan_Pochmann(alphabet):
 for letter in alphabet:
 yield prefix + letter
def Stefan_Pochmann_2(alphabet):
 yield ''
 for prefix in Stefan_Pochmann_2(alphabet):
 yield from map(prefix.__add__, alphabet)
def Ivo_Merchiers(lib):
 for length in count(0):
 for combination in product(lib, repeat=length):
 yield ''.join(combination)
def Ivo_Merchiers_2(lib):
 join = ''.join
 for length in count(0):
 for combination in product(lib, repeat=length):
 yield join(combination)
def Ivo_Merchiers_3(lib):
 for length in count(0):
 yield from map(''.join, product(lib, repeat=length))
def Ivo_Merchiers_chain(lib): # from Peilonrayz
 join = ''.join
 return chain.from_iterable(
 map(join, product(lib, repeat=length))
 for length in count(0)
 )
solutions = Stefan_Pochmann, Stefan_Pochmann_2, Ivo_Merchiers, Ivo_Merchiers_2, Ivo_Merchiers_3, Ivo_Merchiers_chain
for alphabet in lib, 'abc':
 print(alphabet)
 n = 10**7
 
 # Correctness
 sets = map(set, zip(*(words(alphabet) for words in solutions)))
 print(f'same first {n-1:,}:', all(len(s) == 1 for s in islice(sets, n - 1)))
 s = next(sets)
 print(f'same {n:,}th:', len(s) == 1, s)
 print()
 
 # Speed
 tss = [[] for _ in solutions]
 for _ in range(3):
 for words, ts in zip(solutions, tss):
 t = min(repeat(lambda: deque(islice(words(alphabet), n), 0), number=1))
 ts.append(t)
 for words, ts in zip(solutions, tss):
 print(*('%.2f' % t for t in ts), 'seconds ', words.__name__, sep=' ')
 print()
bigger benchmark with more solutions
Source Link

It's probably also a lot faster than yours, although because of your bug, that's not easy to benchmark properly. Peilonrayz' version also has a bug at the moment, but we can compare with Ivo_Merchiers' solution: and a few variations.

First ten million words using your long alphabet of 99 letters (that's up to '021ü'):

0same first 9,999,999: True
same 10,000,000th: True {'9TT8'}
1.14941  1.38 1.38 seconds Stefan_Pochmann
01.24766 1.64  1.63 seconds Stefan_Pochmann_2
2.45 2.45 2.45 seconds Ivo_Merchiers
2.19 2.20 2.21 seconds Ivo_Merchiers_2
1.50 1.49 1.50 seconds Ivo_Merchiers_3
1.20 1.20 1.20 seconds Ivo_Merchiers_chain

First ten million words using alphabet abc (that's up to 'ababaccacabbc'):

0same first 9,999,999: True
same 10,000,000th: True {'abcaccbbcccacbc'}
2.28849  2.43 2.48 seconds Stefan_Pochmann
04.37616 4.17  4.19 seconds Stefan_Pochmann_2
3.91 3.91 3.93 seconds Ivo_Merchiers
3.64 3.66 3.64 seconds Ivo_Merchiers_2
2.74 2.74 2.75 seconds Ivo_Merchiers_3
2.45 2.46 2.45 seconds Ivo_Merchiers_chain
from itertools import product, count
from itertools import, islice, chain
from timeit import repeat
from collections import deque
lib = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz°!"§$%&/()=ß ́`+#-.,><@€|^~–{[]}ÄÖÜäöü'
def Stefan_Pochmann(alphabet):
 yield ''
 for prefix in Stefan_Pochmann(alphabet):
 for character in alphabet:
 yield prefix + character
def Stefan_Pochmann_2(alphabet):
 yield ''
 for prefix in Stefan_Pochmann_2(alphabet):
 yield from map(prefix.__add__, alphabet)
def Ivo_Merchiers(lib):
 for length in count(0):
 for combination in product(lib, repeat=length):
 yield ''.join(combination)
def Ivo_Merchiers_2(lib):
 join = ''.join
for alphabetlength in count(0):
  for combination in product(lib, 'abc'repeat=length):
 print yield join(alphabetcombination)
def Ivo_Merchiers_3(lib):
 for length in count(0):
 yield from map(''.join, product(lib, repeat=length))
def Ivo_Merchiers_chain(lib):  # Correctnessfrom Peilonrayz
 stefanjoin = ''.join
 return chain.from_iterable(
 map(join, product(lib, repeat=length))
 for length in count(0)
 )
solutions = Stefan_Pochmann, Stefan_Pochmann_2, Ivo_Merchiers, Ivo_Merchiers_2, Ivo_Merchiers_3, Ivo_Merchiers_chain
for alphabet in lib, 'abc':
 print(alphabet)
 ivon = Ivo_Merchiers10**7
 
 # Correctness
 sets = map(set, zip(*(words(alphabet) for words in solutions)))
 print(f'same first {n-1:,}:', all(len(s) == i1 for s, i in islice(zip(stefan, ivo)sets, 10**6n - 1)))
 s, i = next(stefan), next(ivosets)
 print(f'same {n:,}th:', len(s) == i1, s)
 print()
 
 # Speed
 tss = [[] for _ in solutions]
 for _ in range(3):
 for words, ts in Stefan_Pochmannzip(solutions, Ivo_Merchierstss):
 timet = min(repeat(lambda: deque(islice(words(alphabet), 10**6n), 0), number=1))
 printts.append(f'{timet)
 for words, ts in zip(solutions, tss):
 print(*('%.3}2f' seconds% t for t in ts), 'seconds ', words.__name__)
 , sep=' ')
 print()

It's probably also a lot faster than yours, although because of your bug, that's not easy to benchmark properly. Peilonrayz' version also has a bug at the moment, but we can compare with Ivo_Merchiers' solution:

First million words using your long alphabet of 99 letters (that's up to '021ü'):

0.149 seconds Stefan_Pochmann
0.247 seconds Ivo_Merchiers

First million words using alphabet abc (that's up to 'ababaccacabbc'):

0.288 seconds Stefan_Pochmann
0.376 seconds Ivo_Merchiers
from itertools import product, count
from itertools import islice
from timeit import repeat
from collections import deque
lib = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz°!"§$%&/()=ß ́`+#-.,><@€|^~–{[]}ÄÖÜäöü'
def Stefan_Pochmann(alphabet):
 yield ''
 for prefix in Stefan_Pochmann(alphabet):
 for character in alphabet:
 yield prefix + character
def Ivo_Merchiers(lib):
 for length in count(0):
 for combination in product(lib, repeat=length):
 yield ''.join(combination)
for alphabet in lib, 'abc':
 print(alphabet)
 # Correctness
 stefan = Stefan_Pochmann(alphabet)
 ivo = Ivo_Merchiers(alphabet)
 print(all(s == i for s, i in islice(zip(stefan, ivo), 10**6 - 1)))
 s, i = next(stefan), next(ivo)
 print(s == i, s)
 print()
 
 # Speed
 for _ in range(3):
 for words in Stefan_Pochmann, Ivo_Merchiers:
 time = min(repeat(lambda: deque(islice(words(alphabet), 10**6), 0), number=1))
 print(f'{time:.3} seconds ', words.__name__)
  print()

It's probably also a lot faster than yours, although because of your bug, that's not easy to benchmark properly. Peilonrayz' version also has a bug at the moment, but we can compare with Ivo_Merchiers' solution and a few variations.

First ten million words using your long alphabet of 99 letters:

same first 9,999,999: True
same 10,000,000th: True {'9TT8'}
1.41  1.38 1.38 seconds Stefan_Pochmann
1.66 1.64  1.63 seconds Stefan_Pochmann_2
2.45 2.45 2.45 seconds Ivo_Merchiers
2.19 2.20 2.21 seconds Ivo_Merchiers_2
1.50 1.49 1.50 seconds Ivo_Merchiers_3
1.20 1.20 1.20 seconds Ivo_Merchiers_chain

First ten million words using alphabet abc:

same first 9,999,999: True
same 10,000,000th: True {'abcaccbbcccacbc'}
2.49  2.43 2.48 seconds Stefan_Pochmann
4.16 4.17  4.19 seconds Stefan_Pochmann_2
3.91 3.91 3.93 seconds Ivo_Merchiers
3.64 3.66 3.64 seconds Ivo_Merchiers_2
2.74 2.74 2.75 seconds Ivo_Merchiers_3
2.45 2.46 2.45 seconds Ivo_Merchiers_chain
from itertools import product, count, islice, chain
from timeit import repeat
from collections import deque
lib = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz°!"§$%&/()=ß ́`+#-.,><@€|^~–{[]}ÄÖÜäöü'
def Stefan_Pochmann(alphabet):
 yield ''
 for prefix in Stefan_Pochmann(alphabet):
 for character in alphabet:
 yield prefix + character
def Stefan_Pochmann_2(alphabet):
 yield ''
 for prefix in Stefan_Pochmann_2(alphabet):
 yield from map(prefix.__add__, alphabet)
def Ivo_Merchiers(lib):
 for length in count(0):
 for combination in product(lib, repeat=length):
 yield ''.join(combination)
def Ivo_Merchiers_2(lib):
 join = ''.join
for length in count(0):
  for combination in product(lib, repeat=length):
  yield join(combination)
def Ivo_Merchiers_3(lib):
 for length in count(0):
 yield from map(''.join, product(lib, repeat=length))
def Ivo_Merchiers_chain(lib):  # from Peilonrayz
 join = ''.join
 return chain.from_iterable(
 map(join, product(lib, repeat=length))
 for length in count(0)
 )
solutions = Stefan_Pochmann, Stefan_Pochmann_2, Ivo_Merchiers, Ivo_Merchiers_2, Ivo_Merchiers_3, Ivo_Merchiers_chain
for alphabet in lib, 'abc':
 print(alphabet)
 n = 10**7
 
 # Correctness
 sets = map(set, zip(*(words(alphabet) for words in solutions)))
 print(f'same first {n-1:,}:', all(len(s) == 1 for s in islice(sets, n - 1)))
 s = next(sets)
 print(f'same {n:,}th:', len(s) == 1, s)
 print()
 
 # Speed
 tss = [[] for _ in solutions]
 for _ in range(3):
 for words, ts in zip(solutions, tss):
 t = min(repeat(lambda: deque(islice(words(alphabet), n), 0), number=1))
 ts.append(t)
 for words, ts in zip(solutions, tss):
 print(*('%.2f' % t for t in ts), 'seconds ', words.__name__, sep=' ')
 print()
added 14 characters in body
Source Link
'' '' + ''
'a' '' + 'a'
'b' '' + 'b'
'c' '' + 'c'
'aa' 'a' + 'a'
'ab' 'a' + 'b'
'ac' 'a' + 'c'
'ba' 'b' + 'a'
'bb' 'b' + 'b'
'bc' 'b' + 'c'
'ca' 'c' + 'a'
'cb' 'c' + 'b'
'cc' 'c' + 'c'
'aaa' 'aa' + 'a'
'aab' 'aa' + 'b'
'aac' 'aa' + 'c'
'aba' 'ab' + 'a'
'abb' 'ab' + 'b'
 ... ...
def words(alphabet):
 yield ''
 for prefix in prefixes(alphabet):
 for characterletter in alphabet:
 yield prefix + characterletter
'' '' + ''
'a' '' + 'a'
'b' '' + 'b'
'c' '' + 'c'
'aa' 'a' + 'a'
'ab' 'a' + 'b'
'ac' 'a' + 'c'
'ba' 'b' + 'a'
'bb' 'b' + 'b'
'bc' 'b' + 'c'
'ca' 'c' + 'a'
'cb' 'c' + 'b'
'cc' 'c' + 'c'
'aaa' 'aa' + 'a'
'aab' 'aa' + 'b'
'aac' 'aa' + 'c'
'aba' 'ab' + 'a'
'abb' 'ab' + 'b'
def words(alphabet):
 yield ''
 for prefix in prefixes(alphabet):
 for character in alphabet:
 yield prefix + character
'' '' + ''
'a' '' + 'a'
'b' '' + 'b'
'c' '' + 'c'
'aa' 'a' + 'a'
'ab' 'a' + 'b'
'ac' 'a' + 'c'
'ba' 'b' + 'a'
'bb' 'b' + 'b'
'bc' 'b' + 'c'
'ca' 'c' + 'a'
'cb' 'c' + 'b'
'cc' 'c' + 'c'
'aaa' 'aa' + 'a'
'aab' 'aa' + 'b'
'aac' 'aa' + 'c'
'aba' 'ab' + 'a'
'abb' 'ab' + 'b'
 ... ...
def words(alphabet):
 yield ''
 for prefix in prefixes(alphabet):
 for letter in alphabet:
 yield prefix + letter
Added benchmark
Source Link
Loading
added 246 characters in body
Source Link
Loading
Source Link
Loading
lang-py

AltStyle によって変換されたページ (->オリジナル) /