Created
September 30, 2025 18:53
-
-
Save mmcclimon/3ba99ad705e6f92f1cbb9574ecc4d1d6 to your computer and use it in GitHub Desktop.
letterboxed-cheat
This file contains hidden or 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
#!/usr/bin/env python | |
import argparse | |
def main(args): | |
lookup = {} | |
for i, group in enumerate(args.groups): | |
for c in group: | |
lookup[c] = i + 1 | |
words = find_candidate_words(args.dict, lookup) | |
print(f"info: examining {len(words)} candidate words") | |
doubles = find_candidate_doubles(words) | |
if not doubles: | |
print("\nno answers found :(") | |
return | |
print(f"info: examining {len(doubles)} pairs to find the best") | |
print("\nbest answers:") | |
find_best_doubles(doubles, args.number) | |
def find_candidate_words(dict_file, lookup): | |
with open(dict_file) as f: | |
return [word.rstrip() for word in f if check_word(lookup, word)] | |
def find_candidate_doubles(words): | |
doubles = [] | |
for first in words: | |
for second in words: | |
if first == second or first[-1] != second[0]: | |
continue | |
if len(set(first + second)) == 12: | |
doubles.append((first, second)) | |
return doubles | |
def find_best_doubles(doubles, num_to_output): | |
def letters_in_common(pair): | |
return len(set(pair[0]).intersection(set(pair[1]))) | |
def total_len(pair): | |
return len(pair[0]) + len(pair[1]) | |
doubles.sort(key=letters_in_common) | |
doubles.sort(key=total_len) | |
for i, d in enumerate(doubles): | |
if i >= num_to_output: | |
break | |
print(d[0], d[1]) | |
def check_word(lookup, word): | |
word = word.rstrip() | |
if len(word) <= 3: | |
return False | |
sides = [lookup.get(c) for c in word] | |
if not all(sides): | |
return False | |
for i in range(1, len(sides)): | |
if sides[i] == sides[i-1]: | |
return False | |
return True | |
if __name__ == "__main__": | |
ap = argparse.ArgumentParser( | |
prog="letterboxed", | |
description="cheat at the times puzzles", | |
) | |
ap.add_argument("--dict", "-d", help="use this dictionary", | |
default="/usr/share/dict/words") | |
ap.add_argument("--number", "-n", help="print top N answers", type=int, default=10) | |
ap.add_argument("groups", nargs=4, help="the sides of the square", | |
metavar="side") | |
args = ap.parse_args() | |
main(args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment