Created
March 3, 2024 20:36
-
-
Save tylerneylon/5fee0139c16e6a3a43368efda279fdc1 to your computer and use it in GitHub Desktop.
A script to help with the Split Decisions word puzzles in the New York Times
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
#!/usr/bin/env python3 | |
# coding: utf-8 | |
""" splits.py | |
Usage: | |
./splits .in,cr.. | |
This will print out all known words that match both patterns with fixed | |
letters per dot. In the above example, one answer pair would be: | |
sinew, screw | |
""" | |
# ______________________________________________________________________ | |
# Imports | |
import re | |
import sys | |
# ______________________________________________________________________ | |
# Functions | |
# This expects a dot/letter pattern in `pat`, as in '..a.'. | |
# This replaces the given (non-dot) letters in `s` with the | |
# letters provided in `pat`. For example: | |
# replace_pattern('hello', 'j...y') # returns 'jelly' | |
def replace_pattern(s, pat): | |
lets = list(s) | |
for i, let in enumerate(pat): | |
if let != '.': | |
lets[i] = let | |
return ''.join(lets) | |
# This expects a string like '.in,cr..', and extracts two | |
# strings like '.in..' and '.cr..'. | |
def parse_patterns(s): | |
# Find the start of the AB,CD substring. | |
start = [i for i, let in enumerate(s) if let != '.'][0] | |
end = start + 5 | |
pat1 = s[:start + 2] + s[end:] | |
pat2 = s[:start] + s[end - 2:] | |
return pat1, pat2 | |
def find_matches(pat1, pat2): | |
# Load our dictionary. | |
with open('/usr/share/dict/words') as f: | |
words = [line.strip().lower() for line in f] | |
wordset = set(words) | |
# Find candidates that match pat1. | |
pat1 = re.compile(pat1) | |
candidates = [w for w in wordset if pat1.fullmatch(w)] | |
# Find complete matches. | |
for c in candidates: | |
replaced = replace_pattern(c, pat2) | |
if replaced in wordset: | |
print(f'{c}, {replaced}') | |
# ______________________________________________________________________ | |
# Main | |
if __name__ == '__main__': | |
if len(sys.argv) < 2: | |
print(__doc__) | |
sys.exit(0) | |
pat1, pat2 = parse_patterns(sys.argv[1]) | |
find_matches(pat1, pat2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment