-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathicosagraph.py
85 lines (67 loc) · 1.96 KB
/
icosagraph.py
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
# prints a graph that when 3-colored can be used to build an icosahedron
# where each face is extruded upwards at an additional center vertex at each
# face, so that every of the 3 faces of every face-pyramid has 3 distinct colors
# and one color on the opposite sides of neighboring face-pyramid faces match.
UNK, R, G, B = -1, 0, 1, 2
class Vertex(object):
def __init__(self, id, color, neighbors, possibleColors):
self.id = id
self.color = color
self.neighbors = neighbors
self.possibleColors = possibleColors
v = [Vertex(i, UNK, set(), set([R, G, B])) for i in range(30)]
def face(a, b, c):
v[a].neighbors.add(b); v[a].neighbors.add(c)
v[b].neighbors.add(a); v[b].neighbors.add(c)
v[c].neighbors.add(a); v[c].neighbors.add(b)
face(0, 1, 2)
face(0, 3, 4)
face(1, 5, 6)
face(2, 7, 8)
face(4, 9, 12)
face(5, 9, 13)
face(6, 10, 14)
face(7, 10, 15)
face(8, 11, 16)
face(3, 11, 17)
face(29 - 4, 29 - 9, 16)
face(29 - 5, 29 - 9, 15)
face(29 - 6, 29 - 10, 14)
face(29 - 7, 29 - 10, 13)
face(29 - 8, 29 - 11, 12)
face(29 - 3, 29 - 11, 17)
face(29 - 0, 29 - 3, 29 - 4)
face(29 - 1, 29 - 5, 29 - 6)
face(29 - 2, 29 - 7, 29 - 8)
face(29 - 0, 29 - 1, 29 - 2)
def assign(i, c):
v[i].color = c
old = {}
for j in v[i].neighbors:
old[j] = v[j].possibleColors.copy()
v[j].possibleColors.discard(c)
return old
def unassign(i, old):
v[i].color = UNK
for k, oldcol in old.iteritems():
v[k].possibleColors = oldcol
assign(0, R)
assign(1, G)
assign(2, B)
# Collect uncolored vertices
# If none, print solution
# Pick vertex with fewest color choices
# For every choice, assign color, recurse, backtrack
def color():
unk = sorted([p for p in v if p.color == UNK],
key=lambda p: len(p.possibleColors))
if len(unk) == 0:
print 'solution found:'
for p in v:
print 'id %d: color %d' % (p.id, p.color)
return
for c in unk[0].possibleColors.copy():
old = assign(unk[0].id, c)
color()
unassign(unk[0].id,old)
color()