Last active
April 16, 2018 00:02
-
-
Save elendiastarman/2440ee665c2e051b5691f501ab432fd4 to your computer and use it in GitHub Desktop.
Distinct line configurations on a cube
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# If each face of a cube is marked with a diagonal line between opposing corners, | |
# how many distinct configurations are there considering rotations and reflections? | |
# Vertex labeling | |
# 2-----3 | |
# |\ |\ | |
# | \ | \ | |
# | 0-----1 | |
# | | | | | |
# 6--|--7 | | |
# \ | \ | | |
# \| \| | |
# 4-----5 | |
reflection = [(0, 4), (1, 5), (2, 6), (3, 7)] | |
rotations = [ | |
# identity | |
[], | |
# 90 deg around face-centered axis | |
[(0, 1, 3, 2), (4, 5, 7, 6)], | |
[(0, 2, 3, 1), (4, 6, 7, 5)], | |
[(0, 1, 5, 4), (2, 3, 7, 6)], | |
[(0, 4, 5, 1), (2, 6, 7, 3)], | |
[(0, 4, 6, 2), (1, 5, 7, 3)], | |
[(0, 2, 6, 4), (1, 3, 7, 5)], | |
# 180 deg around face-centered axis | |
[(0, 3), (1, 2), (4, 7), (5, 6)], | |
[(0, 5), (1, 4), (2, 7), (3, 6)], | |
[(0, 6), (2, 4), (1, 7), (3, 5)], | |
# 180 deg around edge-centered axis | |
[(0, 1), (2, 5), (3, 4), (6, 7)], | |
[(0, 7), (1, 6), (2, 3), (4, 5)], | |
[(0, 2), (1, 6), (3, 4), (5, 7)], | |
[(0, 7), (1, 3), (4, 6), (2, 5)], | |
[(0, 4), (1, 6), (2, 5), (3, 7)], | |
[(0, 7), (1, 5), (2, 6), (3, 4)], | |
# 120 deg around vertex-centered axis | |
[(1, 2, 4), (3, 6, 5)], | |
[(1, 4, 2), (3, 5, 6)], | |
[(0, 3, 5), (2, 7, 4)], | |
[(0, 5, 3), (2, 4, 7)], | |
[(0, 3, 6), (1, 7, 4)], | |
[(0, 6, 3), (1, 4, 7)], | |
[(0, 5, 6), (1, 7, 2)], | |
[(0, 6, 5), (1, 2, 7)], | |
] | |
edge_choices = [ | |
[(0, 3), (1, 2)], | |
[(0, 5), (1, 4)], | |
[(1, 7), (3, 5)], | |
[(3, 6), (2, 7)], | |
[(2, 4), (0, 6)], | |
[(4, 7), (5, 6)], | |
] | |
edge_sets = [] | |
for i in range(64): | |
b = bin(i)[2:] | |
edge_set = [] | |
for j in range(6): | |
if j >= len(b) or b[-j - 1] == '0': | |
edge_set.append(edge_choices[j][0]) | |
else: | |
edge_set.append(edge_choices[j][1]) | |
edge_sets.append(edge_set) | |
def transform(symmetry, edge_set): | |
transformed_edge_set = [] | |
for edge in edge_set: | |
transformed_edge = [] | |
for endpoint in edge: | |
new_endpoint = endpoint | |
for cycle in symmetry: | |
if endpoint in cycle: | |
new_endpoint = cycle[(cycle.index(endpoint) + 1) % len(cycle)] | |
break | |
transformed_edge.append(new_endpoint) | |
transformed_edge_set.append(tuple(sorted(transformed_edge))) | |
return transformed_edge_set | |
def compose(*symmetries): | |
symmetries = list(symmetries) | |
comp = symmetries.pop() | |
while symmetries: | |
sym = symmetries.pop() | |
labels = [] | |
for cycle in comp + sym: | |
labels.extend(cycle) | |
labels = sorted(list(set(labels)), reverse=True) | |
new_comp = [] | |
while labels: | |
new_cycle = [labels.pop()] | |
while len(new_cycle) == 1 or new_cycle[0] != new_cycle[-1]: | |
new_label = new_cycle[-1] | |
for cycle in comp + sym: | |
if new_label in cycle: | |
new_label = cycle[(cycle.index(new_label) + 1) % len(cycle)] | |
new_cycle.append(new_label) | |
if new_label in labels: | |
labels.remove(new_label) | |
if len(new_cycle) > 2: | |
new_comp.append(tuple(new_cycle[:-1])) | |
comp = new_comp | |
return comp | |
def distinct(symmetries, edge_sets): | |
distinct_sets = [] | |
for edge_set in edge_sets: | |
transformed = [] | |
for sym in symmetries: | |
transformed.append(sorted(transform(sym, edge_set))) | |
transformed.sort() | |
if transformed[0] not in distinct_sets: | |
distinct_sets.append(transformed[0]) | |
return distinct_sets | |
all_symmetries = rotations + [compose(rotation, reflection) for rotation in rotations] | |
# # uncomment this if you want interactivity | |
# import IPython # noqa | |
# IPython.embed() | |
total = 0 | |
for symmetry in all_symmetries: | |
total += sum([sorted(transform(symmetry, edge_set)) == sorted(edge_set) for edge_set in edge_sets]) | |
print("Number of distinct configurations: {} / {} = {}".format(total, len(all_symmetries), total / len(all_symmetries))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment