help for this algorithm to change currencies?

3

Based on the algorithm in this hacker rank video, link , I have tried to create my own algorithm that returns the value that I am looking.

Basically, to save you 10 minutes, the algorithm of that video is recursive and stores the information it returns in each iteration somewhere, in the case of the video it is a hashmap. The trick comes because this algorithm is going to make a different action depending on the current values. from there comes the name of "Memoization".

That algorithm returns several combinations that in my case in particular do not help, so try to create my own algorithm.

I need to find the minimum exchange value given a denomination of Mexican coins (1, 2, 5, 10). So what I'm looking for is to create an algorithm that returns the first combination that it finds and fits.

import array

#aqui se crean 4 pilas de 1, 2, 5 y 10 monedas
uno = [1 for i in range(10)]
dos = [2 for i in range(10)]
cinco = [5 for i in range(10)]
diez = [10 for i in range(10)]

monedas = [diez, cinco, dos, uno]
#esta pila almacena las demas pilas de monedas 

cont = len(monedas)-1
#contador para indices de arrays

cont2 = 0
#cuenta las iteraciones que lleva el programa

cant = int(input("dame el cambio a regresar: "))

temp = [cant]
#temporal sera una variable que se ira restando conforme avance el
#metodo en su recursion.

res = ""
# res es el diccionario donde se almacenara
# las combinaciones de monedas resultantes

#el punto de este algoritmo (cambio(etc,...)) es devolver la menor
#combinacion de monedas posibles

# este es un algoritmo que no garantiza el minimo valor logico posible
# de cambio pero intenta maximizar el tiempo

#este algoritmo va devolviendo un valor diferente cada vez que
# se itera, y este valor se va concatenando junto con otros en
# un string, que va a terminar siendo el resultado


def cambio(temp, monedas, cont, res, cont2):

    if (temp >=  monedas[cont]):

    #si la cantidad a dividir en mas monedas es mayor que
    #la moneda seleccionada en la pila de monedas
       temp.insert(cont2+1, temp[cont2] -monedas[cont])

       print("$",temp,"- $",monedas[cont])
       print("cambio: ",res)
       res = res + temp + "-"

       return cambio(temp, monedas, cont, res, cont2)

    if (temp <= monedas[cont]):
       #si el valor a dividir en monedas es menor
       #al valor de la moneda actualmente seleccionada
       #en la lista
       temp.insert(cont2+1, temp[cont2] - monedas[cont])
        ##cont2 lleva el orden de las monedas de mayor a menor
       print("cambio: ",res)
       res = res + temp + "-" 
       return cambio(temp, monedas, cont-1, res, cont2)

    if (temp == monedas[cont]):
       #si la cantidad a calcular es identica al valor de la moneda
       #que esta seleccionada de la pila
       temp.insert(cont2+1, temp[cont2] - monedas[cont])

       print("cambio: ",res)
       res = res + temp + "-" 
       return cambio(temp, monedas, cont-1, res, cont2)

    if (temp == 1):
       ## si el cambio ya alcanzo 1
       temp.insert(cont2+1, temp[cont2] - monedas[cont])
       print("cambio: ",res)
       return 0;

    if (temp == 0):
       ##si el cambio ya alcanzo 0
       print("cambio: ",res)
       return 0
       ## aqui se termina la recursion en el caso de que el valor
       ## restante sea cero



##fin de metodo

cambio(temp, monedas, cont, res, cont2)

When running it, it gives this error:

  

give me the change to return: 8

     

Traceback (most recent call last):

     

File "C: \ Users \ jose miguel \ Desktop \ Python Exercises \ Currency exchange attempt

     

8.py ", line 89, in

     

change (temp, coins, cont, res, cont2)

     

File "C: \ Users \ jose miguel \ Desktop \ Python Exercises \ currency exchange> try 8.py", line 44, in change

     

temp.insert (cont2 + 1, temp [cont2] -coins [cont])

     

TypeError: unsupported operand type (s) for -: 'int' and 'list'

What's wrong? please help me, I have been stuck in this problem for 3 months now: (

    
asked by ayy_chemixd 29.04.2018 в 05:22
source

3 answers

1

To solve this type of problems the ideal is to use the DYNAMIC PROGRAMMING as indicated in the video that you published, now before programming you must implement a recursive function that solves this problem, as it could be ?

First there is to look at a very important aspect that is memorization, that is, imagine that this problem is like a binary tree:

Where each branch is a sub-problem of the problem as such, python divides this problem into many easy and quick small problems to solve, but python is not perfect and instead of solving different problems (which would be the branches of the tree) python repeats these sub-problems many but many times, to the point where this problem to solve it takes many minutes or even hours, for this is memorization, you keep this either in a dictionary or in a matrix for that when a solved problem does not repeat it again.

An example of the number of sub-problems that python repeats is with the Fibonnaci Succession :

If you realize there are sub-problems that he repeats many times, imagine with a very large value for example of 999!

Your error may be due to a confusion of a comparison list with integer as it said @FJSevilla, now with all these clear aspects the code would be something like that.

from sys import stdin

monedas=[1,2,5,10]

def f(i,n):
    global monedas,l
    n=int(n)
    if i>=4 or n<0: return 0
    if l[i][n] != -1: return l[i][n]
    if n ==0: return 1
    else:
        l[i][n]=f(i,n-monedas[i])+f(i+1,n)
        return l[i][n]

def main():
    global l
    l=[]
    for k in range(4):
        l.append([])
        for y in range(30010):
            l[k].append(-1)

    cambio=stdin.readline().strip()
    while cambio:
        n=int(cambio)
        solve=f(0,cambio)
        if solve==1: print("There is only {} way to produce {} cents change.".format(solve,n))
        else: print("There are {} ways to produce {} cents change.".format(solve,n))
        cambio=stdin.readline().strip()
main()

Basically what the code does is check if I have not visited it, if the index is not within the range of the list, and if the change is not 0 (since it returns 1 or 0), if all the above it is then proceeded to check with which cases or coins I can make the change (that is, it tests all possible cases) and also stores it in the matrix of size n * m , where n is the size of the list or coins with which I can change and a size of 30000, I put this large number is because it must have enough space to store up to 30000 data (but it can be changed) so in this case the worst case is 30000, but you can not put this value first because to solve this you need the case of 29999 and this one needs the 29998 and so on, so you should start smaller cases so that you can store them and solve many bigger cases .

  

This problem I solved of the following page Let me count the   ways

    
answered by 29.04.2018 / 20:33
source
1

The previous code published by @ david-o is quite good and I will study it more in depth. Even so, here is the code that resolves my original doubt.

monedas = [1000,500,200,100,50,20,10,5,2,1]
N=int(input("Ingrese la cantidad: "))
    for i in monedas:
        if(N/i>=1):
            if(i>=20):
                print("la cantidad de billetes de " +str(i) +" es: "+str(int(N/i)))
            else:
                print("la cantidad de monedas de " +str(i) +" es: " +str(int(N/i)))
        N=N%i
    
answered by 30.04.2018 в 01:19
0

It is code in python, it is a way to solve the problem of change

print ("DETERMINAR EL CAMBIO")
#DZUL CANUL JESUS GEOVANY
costo = int(input("Cuanto es lo que costo lo que compro lo que compro\n$PRECIO DEL PRODUCTO\n"))
pago = int(input("Digite la cantidad de dinero con lo que usted pago\n"))
dinero = pago-costo """DETERMINAMOS CUANTO ES EL CAMBIO"""
def cambio(cam):
    if cam == 0: #FUNCIO DE PARADA
    return ""#cambio(cam)
    else:
    if cam >= 200:

print ("Un Billete de 200 mas")
#SI EL CAMBIO ES MAYOR A 200 <br/>PODEMOS DAR UN BILLERETE DE 200 SI NO SALTA A LA SIGUIENTE CANTIDAD
        return cambio(cam-200)#IMPORTANTE PARA QUE LA FUNCIONA RECURSIVA  SE IMPLEMENTE
        """
    IMPORTANTE PARA QUE LA FUINCION RECURSIVA  SE SI PODEMOS DAR UN BILLETE DE 200, TENEMOS QUE RESTARLE Y VOLVER A DETERMINAR 
            SI TODAVIA PODEMOS DAR UNO MAS O NO.
            """
    elif cam >= 100:
    print ("Un Billete de 100 mas")
    return cambio(cam-100)
    elif cam >= 50:
        print("Un Billete de 50 mas")
        return cambio(cam-50)
    elif cam >= 20:
    print ("Un Billete de 20 mas")
    return cambio(cam-20)
    elif cam >= 10:
        print ("Una moneda de 10 mas")
            <br/>return cambio(cam-10)
        elif cam >= 5:
        print("Una moneda de 5 mas")
            return cambio(cam-5)
        elif cam >= 2:
        print("Una moneda de 2 mas")
        return cambio(cam-2)
        elif cam >= 1:
        print("Una moneda de 1 mas")
        return cambio(cam-1)


print(cambio(dinero))
print ("Su cambio es : "+str(dinero))
    
answered by 12.10.2018 в 20:33