Как разложить число на слагаемые в двумерный массив?
Пример n = 4
l = [[1,1,1,1],[1,1,2],[1,3],[2,2],[4]]
Как это сделать?
Ответы (2 шт):
Автор решения: Zhihar
→ Ссылка
n = 4
def prepare_arr(arr, n):
arr.append(arr[-1][:-2] + [arr[-1][-2] + arr[-1][-1]] if len(arr) else [1] * n)
if len(arr[-1]) != 1:
prepare_arr(arr, n)
return arr
print(prepare_arr([], n)[:-1])
но для получения всех слагаемых алгоритм конечно иной несколько, да и всех слагаемых чуть больше
ну или так:
n = 4
arr = [[1] * (n - i) + [i] for i in range(1, n)]
print(arr)
Автор решения: vp_arth
→ Ссылка
foo(n, k) возвращает все разбиения числа n, в которых слагаемые не больше k.
foo(0, k) возвращает пустой список
Находим рекуррентное соотношение, как [i] + каждое разбиение из foo(n-i, i) для i = (0, min(n, k))
def foo(n, k = None):
if k is None:
k = n
if n == 0:
return []
result = []
if n <= k:
result.append([n])
for i in range(1, 1+min(n, k)):
for l in foo(n-i, i):
result.append(l + [i])
return result
print(*foo(5), sep='\n')
[5] [1, 1, 1, 1, 1] [1, 1, 1, 2] [1, 2, 2] [2, 3] [1, 1, 3] [1, 4]
То же, с list comprehension:
def foo(n, k = None):
if k is None:
k = n
if n == 0:
return []
return ([[n]] if n<=k else []) + [
l + [i]
for i in range(1, 1+min(n, k))
for l in foo(n-i, i)]