Skip to content

Instantly share code, notes, and snippets.

@XMPPwocky
Last active May 28, 2016 00:50
Show Gist options
  • Save XMPPwocky/2cde69b4fc0b46d03f2a8404459be117 to your computer and use it in GitHub Desktop.
Save XMPPwocky/2cde69b4fc0b46d03f2a8404459be117 to your computer and use it in GitHub Desktop.
import re, string
from collections import Counter
def normalize_word(w):
return re.sub("[^a-z]", "", w.lower())
def load_words():
return list(map(normalize_word, open("/usr/share/dict/american-english-huge", "r").readlines()))
words = load_words()
whitelistchars = string.ascii_lowercase + "_"
init_char = string.ascii_lowercase
def feedback_to_re(fb, possible_chars):
cleaned = fb.strip().replace(" ", "")
for c in cleaned:
if c not in whitelistchars: return None
return re.compile("^"+cleaned.replace("_", "["+possible_chars+"]")+"$")
def feedback_to_chars(fb):
cleaned = fb.strip().replace(" ", "")
return cleaned.replace("_", "")
def refine_candidates(regex, candidates):
return set(filter(lambda w: regex.match(w) is not None, candidates))
def find_candidates(regex): return refine_candidates(regex, words)
def optimal_guess(candidates, knownchars):
candidates = list(candidates)
if not candidates: return None
# they're all the same length
d = Counter()
for candidate in candidates:
for c in set(candidate):
if c not in knownchars: d[c] += 1
total_freq = sum(d.values())
avg_freq = float(total_freq)/len(set(d))
def score(s):
return (s[0], s[1])
return max(map(score, d.items()), key=lambda x: x[1])[0]
class Game:
def __init__(self, template):
self.possible_chars = init_char
self.knownchars = feedback_to_chars(template)
self.candidates = find_candidates(feedback_to_re(template, self.possible_chars))
self.lastguess = None
self.template = template
def guess(self):
if len(self.candidates) == 1: return self.candidates.pop()
self.lastguess = optimal_guess(self.candidates, self.knownchars)
return self.lastguess
def wrong(self):
self.possible_chars = self.possible_chars.replace(self.lastguess, "")
self.update(self.template)
return self.guess()
def update(self, new_template):
self.template = new_template
self.candidates = refine_candidates(feedback_to_re(self.template, self.possible_chars), self.candidates)
self.knownchars = feedback_to_chars(self.template)
return self.guess()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment