Skip to content

Instantly share code, notes, and snippets.

@philpennock
Created November 8, 2013 04:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philpennock/7366452 to your computer and use it in GitHub Desktop.
Save philpennock/7366452 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3.2
"""
polygon: moo.com polygon puzzle solver
moo.com business cards might have a polygon puzzler on a promotional card in
the pack. This tool finds the words.
"""
__author__ = 'syscomet@gmail.com (Phil Pennock)'
import argparse
import sys
import itertools
DEFAULT_WORDFILE = '/usr/share/dict/words'
class Polygon(object):
def __init__(self, letters=None, wordfile=DEFAULT_WORDFILE):
self.wordfile = wordfile
if letters is not None:
self.new_letters(letters)
def new_letters(self, letters):
# works for string or other iter:
self.rawletters = [x.lower() for x in letters]
return self
def loaddict(self, dictfile):
self._wordlist = set(x.strip().lower() for x in open(dictfile).readlines())
def dictwords(self):
if not hasattr(self, '_wordlist'):
self.loaddict(self.wordfile)
return self._wordlist
wordlist = property(
fget=lambda self: self.dictwords(),
fset=lambda self, v: self.loaddict(v),
)
def words_of_len(self, n):
return self.wordlist.intersection(set(''.join(x) for x in itertools.permutations(self.rawletters, n)))
def words_of_at_least_len(self, n):
all = set()
for i in range(n, len(self.rawletters)+1):
all.update(self.words_of_len(i))
return all
def _main(args, argv0):
parser = argparse.ArgumentParser()
parser.add_argument('-w', '--wordfile',
default=DEFAULT_WORDFILE, help='dictionary wordfile')
parser.add_argument('-m', '--minlength',
default=4, type=int, help='minimum letters needed')
parser.add_argument('letters', nargs='+', help='polygon letters')
options = parser.parse_args(args=args)
poly = Polygon(wordfile=options.wordfile)
for letters_item in options.letters:
available = poly.new_letters(letters_item).words_of_at_least_len(options.minlength)
msg = '{comboletters}: {wordcount} words of at least length {minlength}'.format(
comboletters = ''.join(x for x in letters_item),
wordcount = len(available),
minlength = options.minlength,
)
print('{0}\n{1}\n'.format(msg, '-'*len(msg)), end='')
print(' '.join(sorted(available)))
print()
if __name__ == '__main__':
argv0 = sys.argv[0].rsplit('/')[-1]
rv = _main(sys.argv[1:], argv0=argv0)
sys.exit(rv)
# vim: set ft=python sw=2 expandtab :
@philpennock
Copy link
Author

Google Interview Question: how would you optimise this? ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment