Skip to content

Instantly share code, notes, and snippets.

@jsundram
Created May 21, 2020 23:44
Show Gist options
  • Save jsundram/68f375242cf1d39872e5b993ac83bd4b to your computer and use it in GitHub Desktop.
Save jsundram/68f375242cf1d39872e5b993ac83bd4b to your computer and use it in GitHub Desktop.
I got nerd sniped by @vanreece
from collections import defaultdict
import networkx as nx
import string
import matplotlib.pyplot as plt
def get_words(filename='/usr/share/dict/words'):
d = defaultdict(set)
with open(filename) as f:
for line in f:
word = line.strip().lower()
d[len(word)].add(word)
return d
def make_graphs(words_by_len):
letters = string.ascii_lowercase
graphs = {}
for n, words in sorted(words_by_len.items()):
print("Making graph for words of length %d ..." % n)
g = nx.Graph()
for word in words:
for i in range(n):
pre, post = word[:i], word[i+1:]
for x in letters:
candidate = pre + x + post
if candidate != word and candidate in words:
g.add_edge(word, candidate)
graphs[n] = g
return graphs
def save_graph(graph, filename):
# had to tweak figsize so that nodes didn't overlap
plt.figure(figsize=(16, 16))
# circular layout is orderly and legible, compared to spring layout
# but obviously meaningless
pos = nx.circular_layout(graph)
# there may be something better to color by?
colors = [graph.degree(n) for n in graph.nodes]
nx.draw_networkx(graph, pos, node_color=colors, cmap=plt.cm.RdYlGn_r)
plt.savefig(filename)
plt.close()
def longest_simple_path(graph):
# this is the hard part...
# https://en.wikipedia.org/wiki/Longest_path_problem
# We have an undirected graph with cycles, so DAG algos won't help.
return []
def main():
words_by_len = get_words()
for n, words in words_by_len.items():
print("There are %d words of length %d" % (len(words), n))
del words_by_len[1] # trivial word ladder is the alphabet
graphs = make_graphs(words_by_len)
for n, graph in sorted(graphs.items()):
longest = longest_simple_path(graph)
print("longest chain for words of length %s: %s" % (n, len(longest)))
save_graph(graphs[2], "circle-2.png")
return graphs
if __name__ == '__main__':
main()
@jsundram
Copy link
Author

circle-2

words of length 2

@jsundram
Copy link
Author

jsundram commented May 22, 2020

This is probably the best way to do it: https://eprints.cs.univie.ac.at/6197/1/FindingOptimalLongestPaths.pdf
There's an implementation here: http://algo2.iti.kit.edu/kalp/ -- would need to write out to a METIS or DIMACS graph file format, then compile that code, then run it, and then translate the results back into words.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment