[...]
Olá!
Que bom que tentou! :)
Vou tentar desenvolver contigo:
1. Tendo uma lista com o valor das notas e suas quantidades, vamos
colocar isso num dicionário para ficar visualmente agradável
2. Vamos transformar em lista e ordenar do maior para o menor, para
ficar usável e visualmente agradável
3. Montar uma função recursiva que pegue o maior número de notas da
primeira nota da lista, calcular o restante, tirar essa nota da
lista e chamar a função recursivamente até zerar o resto, contudo se
não zerar o resto e acabar as notas, não há caixa para este valor.
4. Para explorar mais possibilidades, vamos remontar o caixa
reduzindo a quantidade da primeira nota utilizada na possibilidade
anterior, retirando esta do caixa se a quantidade for zero.
5. Podemos também explorar os possíveis arranjos das notas, assim
passaremos por todas as possíveis combinações.
6. Ordenar cada combinação encontrada do maior para o menor e
retirar as que são iguais
7. Imprimir o resultado de forma visualmente agradável
Executando:
1. caixa = {50: 10, 20: 10, 10: 10, 5: 10}
2. notas = sorted(caixa.items(), reverse = True)
3.
def quais_notas(caixa, valor):
# se zerar retorna uma lista vazia
if not valor:
return []
# se acabar o caixa retorna uma exceção
if not caixa:
raise SemCaixa
# duplicar a lista
notas_restantes = caixa[:]
# primeira nota e quantidade disponível
nota, qtd = notas_restantes.pop(0)
# cômputo da nota a cima a ser utilizada
utilizadas = min(int(valor / nota), qtd)
# se não utilizou, chama novamente sem essa nota e mesmo valor
if not utilizadas:
return quais_notas(notas_restantes, valor)
# se utilizou, calcula o resto
resto = valor - nota * utilizadas
# retorna lista com essa nota e quantidade utilizada mais
# retorno do calculo das notas restantes com o valor restante
return [(nota, utilizadas)] + quais_notas(notas_restantes,
resto)
4.
possibilidades = []
while True:
notas = sorted(caixa.items(), reverse = True)
try:
possibilidade = quais_notas(notas, valor)
except SemCaixa:
break
possibilidades.append(possibilidade)
# pegando primeira nota e sua quantidade
nota1, qtd1 = possibilidade[0]
# se a quantidade utilizada antes foi de 1, tira do caixa
if qtd1 == 1:
del caixa[nota1]
# senão atualiza a quantidade desta no caixa menos 1
else:
caixa[nota1] = qtd1 - 1
5.
possibilidades = set() # set para evitar duplicidade
caixas = arranjos(sorted([x for x in caixa.items() if x[0] <=
valor],
reverse =
True))
for caixa in caixas:
# duplica o caixa de tuplas para listas para permitir alterações
caixa = [list(x) for x in caixa]
while True:
try:
possibilidade = quais_notas(caixa, valor)
except SemCaixa:
break
# adiciona a possibilidade ordenada e como tupla para o set
possibilidades.add(tuple(sorted(possibilidade, reverse =
True)))
nota1, qtd1 = possibilidade[0]
for n, (nota, qtd) in enumerate(caixa):
if nota == nota1:
break
if qtd1 == 1:
del caixa[n]
else:
caixa[n][1] = qtd1 - 1
6. morreu fazendo "possibilidades = set()" e
"possibilidades.add(tuple(sorted(possibilidade, reverse = True)))"
no item 5 acima
7.
if not possibilidades:
print "Não há caixa para este valor!"
else:
for p, notas in enumerate(sorted(possibilidades, reverse =
True)):
notas = ["%2i x %3i" % n[::-1] for n in notas]
print 'Possibilidade %4i: %s' % (p, ' + '.join(notas))
Código completo em:
https://gist.github.com/JuniorPolegato/9897730
--
[]'s
Junior Polegato