Last active
August 18, 2022 00:00
-
-
Save juandesant/213de5e693ba45d5af9040aefa370d1e to your computer and use it in GitHub Desktop.
Generates anagrams for words found in /usr/share/dict/words
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
from itertools import permutations | |
from functools import reduce | |
from collections import Counter | |
# Iterative product for factorial | |
def factorial(x): return reduce(lambda x,y: x*y , range(1,x+1)) | |
words_file_path = "/usr/share/dict/words" | |
words_file = open(words_file_path, "r") # Valid for macOS; change for Linux, other UNIXes | |
words = { x.rstrip("\n").lower() for x in words_file.readlines() } # create a set for faster membership tests | |
def generate_contained_words(word, min_length=3, dictionary=words): | |
word_characters = list(word.lower()) # split word into list of constit | |
anagrams = set() # creates empty set of word anagrams | |
for n in range(min_length,len(word_characters)+1): | |
if factorial(n) < len({x for x in words if len(x) == n}): | |
candidates = {"".join(x) for x in permutations(word_characters,n) if "".join(x) in dictionary} | |
else: | |
candidates = {"".join(x) for x in dictionary if len(x) == n and Counter(x)==Counter(word)} | |
anagrams = anagrams.union(candidates) | |
return anagrams | |
def generate_anagrams(word, dictionary=words): | |
return generate_contained_words(word, min_length=len(word), dictionary=words) | |
def has_anagrams(word, dictionary=words): | |
result = False | |
if word.lower() in dictionary: | |
num_permutations = factorial(len(word)) | |
potential_words = {x for x in dictionary if len(x)==len(word)} | |
candidates = {} | |
if len(potential_words) > num_permutations: | |
candidates = { "".join(x) for x in set(permutations(list(word.lower()), len(word))) if "".join(x) in dictionary } | |
else: | |
candidates = { | |
x | |
for x in potential_words | |
if set(list(x)) == set(list(word.lower())) and | |
sorted(list(x)) == sorted(list(word.lower())) | |
} | |
if len(candidates) > 1: | |
result = True | |
return result |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment