Skip to content

Instantly share code, notes, and snippets.

@ross
Created March 11, 2024 19:24
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 ross/d7d5827ef35fdb211d732f130a0276fd to your computer and use it in GitHub Desktop.
Save ross/d7d5827ef35fdb211d732f130a0276fd to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
from os.path import exists
from sys import argv, exit
import igraph as ig
def adjacent4(w1, w2):
return (
(w1[0] != w2[0] and w1[1] == w2[1] and w1[2] == w2[2] and w1[3] == w2[3])
or (w1[1] != w2[1] and w1[0] == w2[0] and w1[2] == w2[2] and w1[3] == w2[3])
or (w1[2] != w2[2] and w1[0] == w2[0] and w1[1] == w2[1] and w1[3] == w2[3])
or (w1[3] != w2[3] and w1[0] == w2[0] and w1[1] == w2[1] and w1[2] == w2[2])
)
def adjacent5(w1, w2):
return (
(
w1[0] != w2[0]
and w1[1] == w2[1]
and w1[2] == w2[2]
and w1[3] == w2[3]
and w1[4] == w2[4]
)
or (
w1[1] != w2[1]
and w1[0] == w2[0]
and w1[2] == w2[2]
and w1[3] == w2[3]
and w1[4] == w2[4]
)
or (
w1[2] != w2[2]
and w1[0] == w2[0]
and w1[1] == w2[1]
and w1[3] == w2[3]
and w1[4] == w2[4]
)
or (
w1[3] != w2[3]
and w1[0] == w2[0]
and w1[1] == w2[1]
and w1[2] == w2[2]
and w1[4] == w2[4]
)
or (
w1[4] != w2[4]
and w1[0] == w2[0]
and w1[1] == w2[1]
and w1[2] == w2[2]
and w1[3] == w2[3]
)
)
words_filename = argv[1]
start = argv[2]
try:
end = argv[3]
except IndexError:
end = None
filename = words_filename.replace(".txt", ".gml")
if exists(filename):
graph = ig.load(filename)
else:
with open(words_filename) as fh:
words = fh.read().split()
n = len(start)
adjacent = adjacent4 if n == 4 else adjacent5
n = len(words)
print(f"{n} words")
edges = []
for i, w1 in enumerate(words):
for j, w2 in enumerate(words):
if i == j:
break
if adjacent(w1, w2):
edges.append((i, j))
print(f"{len(edges)} adjacenies")
graph = ig.Graph(n, set(edges))
graph.vs["word"] = words
graph.save(filename)
print(f"graph built and saved")
start_i = graph.vs["word"].index(start)
if end is None:
neighbors = [graph.vs["word"][i] for i in graph.neighbors(start_i)]
print("\n".join(neighbors))
else:
end_i = graph.vs["word"].index(end)
paths = graph.get_all_shortest_paths(start_i, to=end_i)
paths = list(
tuple(graph.vs["word"][i] for i in p)
for p in paths
)
paths.sort()
for path in paths:
print(" -> ".join(path))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment