Created
September 28, 2012 14:21
-
-
Save wuurrd/3800151 to your computer and use it in GitHub Desktop.
This plaything finds the first way one can combine elements in S_4 to create the (12) permutation (group theory).
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
from itertools import combinations_with_replacement, chain, permutations | |
def flatten(l): | |
a = [] | |
for b in l: | |
for c in b: | |
a.append(c) | |
return a | |
class PermutationElement(object): | |
def __init__(self, sequence): | |
self.sequence = sequence | |
self.permutation = False | |
for v in self.sequence: | |
if type(v) == PermutationElement: | |
self.permutation = True | |
break | |
def get_keys(self): | |
if not self.permutation: | |
return list(self.sequence) | |
return flatten([a.get_keys() for a in self.sequence]) | |
def __mul__(self, other_permutation): | |
lists = [] | |
if not len(self.sequence): | |
return other_permutation | |
data = {} | |
seq = self.get_keys() + other_permutation.get_keys() | |
for i in seq: | |
value = other_permutation(self(i)) | |
data[i] = value | |
data = [(k,v) for k, v in data.items() if k!=v] | |
data_dict = dict(data) | |
if not len(data): | |
return PermutationElement([]) | |
keys_left = len(data) | |
while keys_left: | |
current = data.pop(0)[0] | |
if current in flatten(lists): | |
keys_left = len(data) | |
continue | |
new_list = [current] | |
lists.append(new_list) | |
value = current | |
while True: | |
new_value = data_dict[value] | |
if new_value in new_list: | |
break | |
new_list.append(new_value) | |
value = new_value | |
keys_left = len(data) | |
if len(lists) > 1: | |
lists = [PermutationElement(l) for l in lists] | |
else: | |
lists = lists[0] | |
return self.__class__(lists) | |
def __call__(self, val): | |
if not len(self.sequence): | |
return val | |
if not self.permutation: | |
if val in self.sequence: | |
idx = self.sequence.index(val) | |
if idx == len(self.sequence)-1: | |
return self.sequence[0] | |
else: | |
return self.sequence[idx+1] | |
else: | |
return val | |
else: | |
for permutation in self.sequence: | |
val = permutation(val) | |
return val | |
def __str__(self): | |
if self.permutation: | |
return ''.join(str(s) for s in self.sequence) | |
return '(%s)' % (''.join([str(s) for s in self.sequence])) | |
__repr__ = __str__ | |
def __pow__(self, a): | |
val = self | |
for i in range(a-1): | |
val *= self | |
return val | |
def all_subsets(ss, max_size = 15): | |
return chain(*map(lambda x: combinations_with_replacement(ss, x), range(1, max_size))) | |
if __name__ == '__main__': | |
a = PermutationElement([1,2,4,3]) | |
b = PermutationElement([PermutationElement([1,2]), PermutationElement([3,4])]) | |
c = PermutationElement([1,2,3,4]) | |
def find(): | |
count = 0 | |
for k in all_subsets([a,b,c], 5): | |
for m in permutations(k): | |
count += 1 | |
val = m[0] | |
for i, l in enumerate(m): | |
if i == 0: | |
continue | |
val *= l | |
if str(val) in ['(12)', '(21)']: | |
print 'FOUND', m | |
return | |
find() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment