# рассчитываем "уникальные индексы" списка
def unique_index(arr):
elems = []
for e in arr:
if e not in elems:
elems.append(e)
indexes = {v:i for i,v in enumerate(elems)}
result = [indexes[e] for e in arr]
return result
# собственно функция поиска максимального числа
def find_min_period(arr):
for i in range(3, len(arr)//2+1):
# если делится на части
if not len(arr)%i:
# "уникальный индекс" 1-го куска
unique = unique_index(arr[:i])
# делим на части и проверяем, чтобы для каждой "уникальный индекс" был одинаковый
for j in range(i, len(arr), i):
# при первом несовпадении сразу переходим к следующему делителю
if unique != unique_index(arr[j:j+i]):
break
else:
# если все куски оказались с одинаковыми "уникальными индексами" выдаем наше число элементов
return i
return None
print(find_min_period([0, 1, 1, 2, 1, 3, 4, 4, 5, 4, 5, 6, 6, 3, 6]))
# 5
print(find_min_period([0, 1, 1, 2, 1, 1, 3, 4, 4, 40, 4, 4]))
# 3
print(find_min_period([0, 1, 1, 2, 1, 1, 3, 4, 4, 4, 4, 12]))
# None
import numpy as np
a = [0, 1, 1, 2, 1, 3, 4, 4, 5, 4]
N = len(a)
a = np.array(a)
for n in range(3, N):
if N % n == 0:
b = a.reshape(-1, n)
b = np.diff(b, axis=1)
if np.all(b == b[0]):
print(n)
from operator import sub
a = [0, 1, 1, 2, 1, 3, 4, 4, 5, 4]
N = len(a)
for n in range(3, N):
if N % n != 0:
continue
matrix = list(zip(*[iter(a)]*n))
for i, row in enumerate(matrix):
matrix[i] = map(sub, row[1:], row[:-1])
transposed = zip(matrix)
row_to_set = map(set, transposed)
set_to_len = map(len, row_to_set)
if len(set(set_to_len)) == 1:
print(n)
def get_list_part_count(lst: list, start_divider):
# ищем наименьшее количество частей списка
ln = len(lst)
while True:
if ln % start_divider != 0:
start_divider += 1
else:
break
return start_divider
def find_max_item_val_in_dict(dc: dict):
# ищем максимальное значение элемента словаря
# предполагаем, что отрицательных чисел в наших списках не будет
max_val = -1
result_item = None
for key in dc:
if dc[key] > max_val:
max_val = dc[key]
result_item = key
return result_item
def split_list_to_parts(lst, part_count):
# делим список на части, заданные в параметре part_count
part_len = int(len(lst) / part_count) # длина одной части
y = [] # результирующий список
for multiplier in range(1, part_count + 1):
# заполняем наш список срезами исходного
y.append(lst[(part_len * multiplier) - part_len:part_len * multiplier])
return y
def find_periodic_seq(seq, start_divider):
# получаем наш разделенный список
splitted_list = split_list_to_parts(seq, get_list_part_count(seq, start_divider))
# тут будут храниться наши последовательности
counters = []
# нужно больше циклов!!!
# пробегаем по нашему расщепенцу
for sub_list in splitted_list:
dc = {}
for element in sub_list:
# заполняем словарь dc данными, сколько раз каждый элемент встречается в последовательности
# count намеренно не использовал
try:
dc[element] += 1
except KeyError:
dc[element] = 1
# находим элемент, котрый максимально часто встречается в последовательности
max_item = find_max_item_val_in_dict(dc)
lst = []
# собираем индексы, на которых находятся наши элементы и запихиваем в список lst
for pos, element in enumerate(sub_list):
if element == max_item:
lst.append(pos)
# список со списками индексов максимально часто повторяющихся элементов, предварительно разбитого списка!
counters.append(lst)
# если длина списка == количеству повторений первого элемента -> наш список содержит одинаковые элементы
if len(counters) == counters.count(counters[0]):
return counters[0]
else:
return None
if __name__ == '__main__':
# не улетаем в небеса и ограничиваем бесконечный цикл
stop_cycles = 10
current_cycles = 1
# исходный список
lst = [0, 1, 1, 2, 1, 3, 4, 4, 5, 4, 5, 6, 6, 3, 6]
# минимальное количество элементов в каждой части при дроблении списка на части
start_divider = 3
while True:
if current_cycles > stop_cycles:
print(f'Can not find sequence with {current_cycles} cycles, stopping :(')
break
# вызываем нашу основную функцию
result = find_periodic_seq(lst, start_divider)
if not result:
# если ничего не нашлось - увеличиваем минимальную длину части на 1
start_divider += 1
else:
print(f'seq was founded with {current_cycles} cycles! {result}')
break