Created
June 22, 2012 20:16
-
-
Save josephturnerjr/2974938 to your computer and use it in GitHub Desktop.
Hanging solver in Python vs. Coffeescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Hash-based set implementation from the Coffeescript cookbook | |
# http://coffeescriptcookbook.com/chapters/arrays/removing-duplicate-elements-from-arrays | |
Array::unique = -> | |
output = {} | |
output[@[key]] = @[key] for key in [0...@length] | |
value for key, value of output | |
class Solver | |
constructor: (data) -> | |
words = new String(data).trim().split(' ') | |
words = (x.toLowerCase() for x in words) | |
words = words.unique() | |
# Parse the words into lengths | |
lengths = (w.length for w in words).unique() | |
word_sets = (x for x in words when x.length == l for l in lengths) | |
@words = {} | |
@words[key] = word_sets[i] for key, i in lengths | |
solve: (query, tried) -> | |
# Query is . for unknowns, letters filled in as appropriate | |
# The words can't contain letters that are already there | |
# Also not the letters we've already tried | |
bad_chars = (x for x in query when x != '.') | |
bad_chars = bad_chars.concat((if tried.length then tried.join("") else [])).unique() | |
# Build a pattern for those letters | |
off_limits = bad_chars.join("") | |
ignore_pattern = "[^#{off_limits}]" | |
# Replace the wildcards with the pattern | |
reg = new RegExp(query.replace /\./g, ignore_pattern) | |
# Words that match the resulting pattern | |
possibilities = [] | |
if @words[query.length]? | |
possibilities = (x for x in @words[query.length] when x.match(reg)) | |
return new SolverResults(possibilities, bad_chars) | |
class SolverResults | |
constructor: (possibilities, bad_chars) -> | |
@possibilities = possibilities | |
@bad_chars = bad_chars | |
get_possibilities: -> | |
return @possibilities | |
get_letter_freqs: -> | |
if not @scores? | |
if @possibilities.length is 0 | |
@scores = [] | |
else | |
# Calculate the most likely unguessed letter | |
# ALL OF THE LETTERS! | |
concat = @possibilities.join("").split("") | |
# Calculate the letter frequencies for each non-guessed letter, | |
# the max being the most likely | |
chars = (x for x in concat.unique() when x not in @bad_chars) | |
@scores = ([(y for y in @possibilities when x in y).length, x] for x in chars) | |
@scores.sort((a,b) -> b[0] - a[0]) | |
return @scores |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
class Solver(object): | |
def __init__(self, data): | |
words = set(map(lambda x: x.lower(), data.split())) | |
# Parse the words into lengths | |
lengths = set(map(len, words)) | |
word_sets = [filter(lambda x: len(x) == l, words) for l in lengths] | |
self.words = dict(zip(lengths, word_sets)) | |
def solve(self, query, tried): | |
# Query is . for unknowns, letters filled in as appropriate | |
# The words can't contain letters that are already there | |
# Also not the letters we've already tried | |
bad_chars = set(filter(lambda x: x != '.', query) + "".join(tried)) | |
# Build a pattern for those letters | |
off_limits = "".join(bad_chars) | |
ignore_pattern = "[^%s]" % (off_limits,) | |
# Replace the wildcards with the pattern | |
reg = re.sub('\.', ignore_pattern, query) | |
# Words that match the resulting pattern | |
possibilities = filter(lambda x: re.match(reg, x), | |
self.words[len(query)]) | |
return SolverResults(possibilities, bad_chars) | |
class SolverResults(object): | |
def __init__(self, possibilities, bad_chars): | |
self.possibilities = possibilities | |
self.bad_chars = bad_chars | |
self.scores = None | |
def get_possibilities(self): | |
return self.possibilities | |
def get_letter_freqs(self): | |
if not self.scores: | |
if not self.possibilities: | |
self.scores = [] | |
else: | |
# Calculate the most likely unguessed letter | |
# ALL OF THE LETTERS! | |
chars = set("".join(self.possibilities)) - self.bad_chars | |
# Calculate the letter frequencies for each non-guessed letter, | |
# the max being the most likely | |
self.scores = [[len(filter(lambda w: c in w, self.possibilities)), c] for c in chars] | |
self.scores.sort(reverse=True) | |
return self.scores |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment