A simple algorithm for generating combinations with repetitions : we will present our set as a set of numbers. Then all possible combinations with repetitions are simply all possible numbers with a given digit capacity on a given set of numbers. The easiest way to get all the possible numbers is to choose a certain "zero" and gradually increase it.
Let's see how we do it in arithmetic. Suppose we have the digits A, B and C and the maximum digit capacity is 2. For the "zero" we take the first number, i.e. A (and taking into account digit capacity: AA)
Then, increasing this number by 1, we first increase the first digit by 1 (i.e., take the next possible digit), and if we overflow (i.e., there are no more digits available), then reset the current digit to "zero "and increment the next digit of the number by 1, etc.
A few examples:
ноль - AA AA + 1 = AB (т.к. B - следующая цифра после A) AB + 1 = AC (т.к. C - следующая цифра после B) AC + 1 = BA (т.к. после C нет доступных цифр, то обнуляем первый разряд и увеличиваем на 1 второй разряд) и т.д.
Those. The algorithm for generating our combinations is simple:
- We generate the first number of necessary digit capacity (zero)
- Increase the number obtained in the previous step by 1
- Repeat point 2 until we get an overflow in the last digit (i.e. the next possible number will be already with a bit greater than the specified one)
The algorithm for increasing the number by 1 is also simple:
- At the entrance we have possible digits of the number, the number itself and the digit that we are going to increase
- Increase current bit by 1
- If an overflow has occurred, reset the current discharge and repeat the algorithm for the next discharge.
- If an overflow occurred, but the current bit — the last one in the selected capacity — we received the maximum number in the selected capacity
In python code, it looks something like this:
def increase_number(digits, number, increased_index = 0): number = list(number) total_digits_count = len(digits) number_digits_count = len(number) # было переполнение в последнем доступном разряде if increased_index >= number_digits_count: return False current_digit = number[increased_index] current_digit_index = digits.index(current_digit) # если в текущем разряде переполнение - увеличиваем на 1 следующий разряд if current_digit_index + 1 >= total_digits_count: number[increased_index] = digits[0] return increase_number(digits, number, increased_index + 1) # в текущий разряд пишем следующую по списку цифру number[increased_index] = digits[current_digit_index + 1] return number def product(digits, repeat=3): all_products = [] current_number = [digits[0]] * repeat while True: yield current_number current_number = increase_number(digits, current_number) # было переполнение последнего разряда, больше чисел нет if current_number == False: break myarray=['5', 'O', 'S'] result = product(myarray, 2) for number in result: print (''.join(number)) # Вывод: # 55 # O5 # S5 # 5O # OO # SO # 5S # OS # SS
I did not bother, so here the numbers are a little upside down. Those. instead of the number 0123, the output will be 3210, but this in no way affects the result.
(index + 1) % 3In the evening I will sign the algorithm - BOPOH