Playing with trie graph stuff
This commit is contained in:
parent
133080bf14
commit
bac6f87920
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,6 +6,7 @@
|
|||||||
*.hex
|
*.hex
|
||||||
*.log
|
*.log
|
||||||
*env
|
*env
|
||||||
|
*.dat
|
||||||
|
|
||||||
/oldstuff/intro-to-crafty/lib/crafty.js
|
/oldstuff/intro-to-crafty/lib/crafty.js
|
||||||
/oldstuff/intro-to-crafty/assets/*
|
/oldstuff/intro-to-crafty/assets/*
|
||||||
|
98
graphy/grid.py
Normal file
98
graphy/grid.py
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
from trie import Trie
|
||||||
|
|
||||||
|
DEBUG = os.environ.get('DEBUG', '') == '1'
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
dim = int(os.environ.get('DIM', '3'))
|
||||||
|
words_dat_file = os.environ.get('WORDS_DAT', 'words-en.dat')
|
||||||
|
|
||||||
|
edges = list(map(lambda s: s.strip(), sys.stdin.read().split()))
|
||||||
|
edge_map = {}
|
||||||
|
|
||||||
|
valid_words = Trie.from_dat_file(words_dat_file)
|
||||||
|
|
||||||
|
if len(edges) % dim != 0:
|
||||||
|
raise ValueError('edges length={!r} not divisible by dim={!r}'.format(
|
||||||
|
len(edges), dim))
|
||||||
|
|
||||||
|
for row in range(0, dim):
|
||||||
|
for col in range(0, dim):
|
||||||
|
idx = (row * dim) + col
|
||||||
|
if idx >= len(edges):
|
||||||
|
continue
|
||||||
|
edge_map[(row, col)] = Edge((row, col), edges[idx])
|
||||||
|
|
||||||
|
for (row, col), edge in edge_map.items():
|
||||||
|
for sibling in ((row, col - 1), (row, col + 1), (row - 1, col),
|
||||||
|
(row + 1, col), (row - 1, col - 1), (row - 1, col + 1),
|
||||||
|
(row + 1, col + 1), (row + 1, col - 1)):
|
||||||
|
debug('checking {!r} sibling {!r}'.format((row, col), sibling))
|
||||||
|
if edge_map.get(sibling) is not None:
|
||||||
|
edge.siblings.add(edge_map[sibling])
|
||||||
|
debug(' added sibling {!r} to {!r}'.format(sibling, edge))
|
||||||
|
|
||||||
|
for origin in sorted(edge_map.keys()):
|
||||||
|
for dest in sorted(edge_map.keys()):
|
||||||
|
if origin == dest:
|
||||||
|
continue
|
||||||
|
|
||||||
|
debug('getting paths from origin={!r} to dest={!r}'.format(
|
||||||
|
origin, dest))
|
||||||
|
|
||||||
|
for path in dfs_paths(edge_map, valid_words, origin, dest):
|
||||||
|
print(''.join(list(map(lambda e: edge_map[e].value, path))))
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
class Edge:
|
||||||
|
def __init__(self, id_, value, siblings=None):
|
||||||
|
self.id = id_
|
||||||
|
self.value = value
|
||||||
|
self.siblings = siblings if siblings is not None else set()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return 'Edge({!r}, {!r}, siblings={!r})'.format(
|
||||||
|
self.id, self.value, set(map(lambda s: s.id, self.siblings)))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sibling_ids(self):
|
||||||
|
return set(map(lambda s: s.id, self.siblings))
|
||||||
|
|
||||||
|
|
||||||
|
def dfs_paths(edge_map, valid_words, origin, dest, path=None):
|
||||||
|
if path is None:
|
||||||
|
debug(' starting new path from {!r}'.format(origin))
|
||||||
|
path = [origin]
|
||||||
|
if origin == dest:
|
||||||
|
debug(' origin={!r} reached dest={!r}, yielding path'.format(
|
||||||
|
origin, dest))
|
||||||
|
if len(path) > 2 and len(path) < 17:
|
||||||
|
yield path
|
||||||
|
|
||||||
|
if ''.join(path) not in valid_words:
|
||||||
|
return
|
||||||
|
|
||||||
|
next_steps = edge_map[origin].sibling_ids - set(path)
|
||||||
|
if not next_steps:
|
||||||
|
return
|
||||||
|
|
||||||
|
debug(' origin={!r} dest={!r} checking next steps in {!r}'.format(
|
||||||
|
origin, dest, next_steps))
|
||||||
|
for next_step in edge_map[origin].sibling_ids - set(path):
|
||||||
|
yield from dfs_paths(edge_map, next_step, dest, path + [next_step])
|
||||||
|
|
||||||
|
|
||||||
|
def debug(msg):
|
||||||
|
if not DEBUG:
|
||||||
|
return
|
||||||
|
print(msg, file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
77
graphy/trie.py
Normal file
77
graphy/trie.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import os
|
||||||
|
import pickle
|
||||||
|
import sys
|
||||||
|
|
||||||
|
DEBUG = os.environ.get('DEBUG', '') == '1'
|
||||||
|
|
||||||
|
|
||||||
|
class Trie:
|
||||||
|
def __init__(self, value):
|
||||||
|
self.value = value
|
||||||
|
self.children = []
|
||||||
|
self.is_leaf = False
|
||||||
|
|
||||||
|
def add(self, value):
|
||||||
|
node = self
|
||||||
|
for ch in value:
|
||||||
|
child_matches = False
|
||||||
|
for child in node.children:
|
||||||
|
if child.value == value:
|
||||||
|
node = child
|
||||||
|
child_matches = True
|
||||||
|
break
|
||||||
|
if not child_matches:
|
||||||
|
to_add = Trie(value)
|
||||||
|
node.children.append(to_add)
|
||||||
|
node = to_add
|
||||||
|
node.is_leaf = True
|
||||||
|
|
||||||
|
def __contains__(self, search):
|
||||||
|
node = self
|
||||||
|
if not self.children:
|
||||||
|
return False
|
||||||
|
for ch in search:
|
||||||
|
found = False
|
||||||
|
for child in node.children:
|
||||||
|
if child.value == ch:
|
||||||
|
found = True
|
||||||
|
node = child
|
||||||
|
break
|
||||||
|
if not found:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
words_file = os.environ.get('WORDS', 'words-en.txt')
|
||||||
|
words_dat_file = os.environ.get('WORDS_DAT', 'words-en.dat')
|
||||||
|
words_size_range = range(*(
|
||||||
|
map(lambda s: int(s),
|
||||||
|
os.environ.get('WORDS_SIZE_RANGE', '2-15').split('-'))))
|
||||||
|
|
||||||
|
valid_words = Trie('')
|
||||||
|
|
||||||
|
with open(words_file) as inwords:
|
||||||
|
debug('reading from {!r}'.format(words_file))
|
||||||
|
for word in inwords.read().split():
|
||||||
|
if len(word) not in words_size_range:
|
||||||
|
continue
|
||||||
|
|
||||||
|
debug('adding {!r} to valid words'.format(word))
|
||||||
|
valid_words.add(word)
|
||||||
|
|
||||||
|
with open(words_dat_file, 'wb') as outdat:
|
||||||
|
debug('writing valid words to {!r}'.format(words_dat_file))
|
||||||
|
pickle.dump(valid_words, outdat)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def debug(msg):
|
||||||
|
if not DEBUG:
|
||||||
|
return
|
||||||
|
print(msg, file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
90509
graphy/words-en.txt
Normal file
90509
graphy/words-en.txt
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user