summaryrefslogtreecommitdiff
path: root/graph.lua
blob: 2b756d42d0e729e6b7069f0ddec68a87fbcb51be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env lua
local automaton = require "automaton"
local generate = require "generate"
local reading = require "reading"
local init = automaton(generate.trange(1, 25))


local function add_node (graph, id)
	local node = graph[id]
	if node then
		return node
	end
	node = {
		id = id,
		outcoming = {},
		incoming = {},
		paths = {},
	}
	graph[id] = node
	return node
end


local function add_edges (graph, state, kind)
	for dst, src in ipairs(state) do
		local a = add_node(graph, src)
		local b = add_node(graph, dst)
		a.outcoming[kind] = b
		b.incoming[kind] = a
	end
end


local graph = {}
add_edges(graph, init:left(), "left")
add_edges(graph, init:right(), "right")
add_edges(graph, init:pivot(), "centre")
add_edges(graph, init:up(), "up")
add_edges(graph, init:down(), "down")
local map = {
	centre = 0,
	up = 1,
	right = 2,
	down = 3,
	left = 4,
}


local function trigram (path)
	return reading.trigram_to_value(
		map[path[1]],
		map[path[2]],
		map[path[3]])
end


local function shallow_copy (obj)
	local new = {}
	for k, v in ipairs(obj) do
		new[k] = v
	end
	return new
end


local function generate_paths_from (start, length)
	local queue = {{node=start, length=0, path={}}}
	while #queue > 0 do
		local entry = table.remove(queue, 1)
		if entry.length == length then
			local paths = entry.node.paths[start.id] or {}
			table.insert(paths, entry.path)
			entry.node.paths[start.id] = paths
		end
		if entry.length < length then
			for kind, node in pairs(entry.node.incoming) do
				local path = shallow_copy(entry.path)
				table.insert(path, 1, kind)
				table.insert(queue, {node=node, length=entry.length + 1, path=path})
			end
		end
	end
end


local function error_no_path_between (start, dest)
	if not start.paths[dest.id] then
		io.stderr:write(string.format("cannot move from %d to %d\n", start.id, dest.id))
	end
end


generate_paths_from(graph[3], 3)
generate_paths_from(graph[19], 3)
for _, node in ipairs(graph) do
	for target, paths in pairs(node.paths) do
		for _, path in ipairs(paths) do
			print(string.format("%d,%d,%d,%s,%s,%s", node.id, target, trigram(path), path[1], path[2], path[3]))
		end
	end
	error_no_path_between(node, graph[3])
	error_no_path_between(node, graph[19])
end