www while suma resueltos programas paso111 org numeros mclibre lecciones for ejercicios contador consultar condiciones con ciclos python list recursion sum

python - resueltos - suma de n numeros en c con while



Genera todas las listas posibles de longitud N que suman a S en Python (1)

Intento generar todas las listas posibles de Length N que suman S. He escrito un código para hacerlo, pero en cualquier cosa grande (en particular, quiero N = 5, S = 100), me encuentro con la memoria errores de desbordamiento

Estoy buscando una mejor solución al problema, o una forma de mejorar mi código para poder ejecutarlo en N = 5, S = 100. Estos dos programas a continuación trabajan en conjunto para crear todas las combinaciones de números posibles en listas anidadas, y luego volver a trabajarlas para que tengan el formato correcto. Algunos ejemplos de salida se reproducen a continuación.

Sé que mi código no es el mejor. Soy un ingeniero de oficio (lo sé, lo sé), así que codificar no es exactamente mi fuerte. Agradezco cualquier ayuda que pueda brindar.

EDITAR: Solo quería aclarar algunas cosas. Primero, está bien tener cero en las listas, las listas pueden contener múltiplos del mismo número, y el orden de los números en las listas es importante.

def nToSum(N,S): '''''' Creates a nested list of all possible lists of length N that sum to S'''''' if N <= 1: #base case return [S] else: L = [] for x in range(S+1): #create a sub-list for each possible entry of 0 to S L += [[x,nToSum(N-1,S-x)]] #create a sub-list for this value recursively return L def compress(n=[],L): #designed to take in a list generated by nToSum ''''''takes the input from nToSum as list L, and then flattens it so that each list is a top level list. Leading set n is the "prefix" list, and grows as you climb down the sublists'''''' if type(L[0]) == int: #base case: you have exposed a pure integer return [n+L] #take that integer, and prepend the leading set n else: Q = [] for x in L: # look at every sublist Q += compress(n+[x[0]],x[1]) # for each sublist, create top level lists recursively return Q # note: append x[0] to leading set n >>> nToSum(3,3) [[0, [[0, [3]], [1, [2]], [2, [1]], [3, [0]]]], [1, [[0, [2]], [1, [1]], [2, [0]]]], [2, [[0, [1]], [1, [0]]]], [3, [[0, [0]]]]] >>> compress([],nToSum(3,3)) [[0, 0, 3], [0, 1, 2], [0, 2, 1], [0, 3, 0], [1, 0, 2], [1, 1, 1], [1, 2, 0], [2, 0, 1], [2, 1, 0], [3, 0, 0]]


Usar un generador ahorra memoria, y xrange lugar de range (en Python 2.X, de todos modos), esto es lo que se me ocurrió. Es muy similar a su nToSum sin necesidad de compress .

def f(n,s): if n == 1: yield (s,) else: for i in xrange(s + 1): for j in f(n - 1,s - i): yield (i,) + j L = list(f(5,100)) print ''total permutations:'',len(L) # First and last 10 of list for i in L[:10] + L[-10:]: print i

Salida

total permutations: 4598126 (0, 0, 0, 0, 100) (0, 0, 0, 1, 99) (0, 0, 0, 2, 98) (0, 0, 0, 3, 97) (0, 0, 0, 4, 96) (0, 0, 0, 5, 95) (0, 0, 0, 6, 94) (0, 0, 0, 7, 93) (0, 0, 0, 8, 92) (0, 0, 0, 9, 91) (98, 0, 2, 0, 0) (98, 1, 0, 0, 1) (98, 1, 0, 1, 0) (98, 1, 1, 0, 0) (98, 2, 0, 0, 0) (99, 0, 0, 0, 1) (99, 0, 0, 1, 0) (99, 0, 1, 0, 0) (99, 1, 0, 0, 0) (100, 0, 0, 0, 0)