Mathematics
Algorithms
Logic
Numbers
If we have planty of objects like this: ['a', 'b', 'c']
then we can build all permutation:
0 – abc 1 – acb 2 – bac 3 – bca 4 – cab 5 – cba
Any of them permutations may be calculated by their index number without calculated others.
import math
class SequencePermutation(object):
def __init__(self, plenty_object, count_item):
self.plenty_object = list(plenty_object)
self.count_item = count_item
self.power_plenty = len(plenty_object)
@staticmethod
def calc_count_permutation(n, k):
return int(math.factorial(n) / math.factorial(n - k))
def __getitem__(self, index):
current_mod = index
plenty = self.plenty_object.copy()
for i in range(self.count_item - 1):
perm_count = self.calc_count_permutation(self.power_plenty - i - 1, self.count_item - i - 1)
current_index = current_mod // perm_count
yield plenty[current_index]
plenty.pop(current_index)
current_mod = current_mod % perm_count
yield plenty[current_mod]
Test.describe("SequencePermutation")
Test.describe("should correct calculate for permutations with three by three")
sq_per_master = SequencePermutation(('a','b','c'), 3)
Test.assert_equals(['a', 'b', 'c'], list(sq_per_master[0]))
Test.assert_equals(['a', 'c', 'b'], list(sq_per_master[1]))
Test.assert_equals(['c', 'a', 'b'], list(sq_per_master[4]))
Test.describe("should correct calculate for permutations with one item")
sq_per_master = SequencePermutation(('a','b','c'), 1)
Test.assert_equals(['a'], list(sq_per_master[0]))
Test.assert_equals(['b'], list(sq_per_master[1]))
Test.assert_equals(['c'], list(sq_per_master[2]))
Test.describe("should correct calculate for permutations with two items")
sq_per_master = SequencePermutation(('a','b','c'), 2)
Test.assert_equals(['a', 'b'], list(sq_per_master[0]))
Test.assert_equals(['a', 'c'], list(sq_per_master[1]))
Test.assert_equals(['c', 'a'], list(sq_per_master[4]))