Skip to content

Instantly share code, notes, and snippets.

@glyphobet
Last active August 29, 2015 14:23
Show Gist options
  • Save glyphobet/cf30bc14b6e48ce5b4f2 to your computer and use it in GitHub Desktop.
Save glyphobet/cf30bc14b6e48ce5b4f2 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3.4
# A response to http://nbviewer.ipython.org/url/norvig.com/ipython/Fred%20Buns.ipynb
# Read more about it at https://blog.glyphobet.net/essay/2770
import itertools
from collections import Counter
lock_size = 10
WORDS = set(w.lower() for w in open('words4.txt').read().split())
norvig_improved_wordlock = ['spcmthdlfb', 'leyhwruoai', 'enmlrtacso', 'dsnpaylkte']
norvig_improved_random = ['dwbfptlmsc', 'aohryuiwel', 'atocsinerl', 'eyadhstlnk']
cat = ''.join
def combinations(lock):
"Return a list of all combinations that can be made by this lock."
return set(map(cat, itertools.product(*lock)))
def words_from(lock):
"A list of words that can be made by lock."
return [c for c in combinations(lock) if c in WORDS]
def word_count(lock):
return len(words_from(lock))
def print_common(counters, depth=12):
most_commons = [c.most_common(depth) for c in counters]
for row in zip(*most_commons):
for col in row:
print('{}:{}'.format(*col), end='\t')
print()
def print_lock(lock):
print("Lock: " + ' '.join((''.join(sorted(t))).upper() for t in lock), end='')
print(',', word_count(lock), 'words')
def main():
for l in (norvig_improved_wordlock, norvig_improved_random):
print_lock(l)
counters = [Counter(), Counter(), Counter(), Counter()]
for word in WORDS:
word = word.lower().strip()
for i,c in enumerate(word):
counters[i][c] += 1
lock = ['', '', '', '']
while min(len(l) for l in lock) < 10:
# print_common(counters)
best_count = 0
best_index = None
best_letter = None
for i, c in enumerate(counters):
if len(lock[i]) >= lock_size:
continue
letter, count = c.most_common(1)[0]
if (best_count < count):
best_count = count
best_index = i
best_letter = letter
print("Best choice is {}:{} at index {}".format(best_letter, best_count, best_index))
del counters[best_index][best_letter]
lock[best_index] += best_letter
# print_lock(lock)
print_lock(lock)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment