Skip to content

Instantly share code, notes, and snippets.

@tylerneylon
Created March 3, 2024 20:36
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 tylerneylon/5fee0139c16e6a3a43368efda279fdc1 to your computer and use it in GitHub Desktop.
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
#!/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