Python finding most efficient combination of coins to reach item value - python

If i've got 2 variables that contain the price needed, and the value of coins provided in cents. E.G, coins = [5, 5, 10, 20, 50, 100, 100, 200], and total = 250. I've tried a number of approaches, but I can't seem to find anything that works properly.
For example, if i've got coins = [10, 10, 20, 20, 20, 100, 100] and total = 250 it returns [10, 20, 20, 100, 100], ordering not important.
I've been trying find a solution to this for a while. Thanks for any help

For this to work, you would have to sort your coins in descending order, or use reversed(coinList) instead of coinList in the first for loop and vice versa in the second if you would like to sort them forwards:
total = 250
value = 0
coins = []
coinList = [100, 100, 20, 20, 20, 10, 10]
for coin in coinList:
if value + coin <= total:
value += coin
coins.append(coin)
else:
continue
if value >= total:
break
else:
for coin in reversed(coinList):
value += coin
coins.append(coin)
if value >= total:
break
print coins

Related

Sum of value in array and condition check - Python [duplicate]

This question already has answers here:
Sum of elements of subarrays is equal to a target value in Python
(4 answers)
Closed 1 year ago.
I have the following variables:
arr = [50, 100, 100, 100, 200, 200]
inp = 450
in the inp variable, I receive data from the user, the user can enter any value between the minimum array and the maximum amount of values in the array (50 and 750).
I want to return the values in the array that make up the amount equal to the value in the variable inp
In this situation inp = 450 there are two variants: 50 + 100 + 100 + 200 or 50 + 200 + 200. I'm only interested in one of them.
how can i continue the following code:
import sys
arr = [50, 100, 100, 100, 200, 200]
inp = 450
sum = 0
res = []
for x in arr:
if x == inp:
res = x
print(res)
sys.exit()
sum = sum+x
res.append(x)
if sum == inp:
print(res)
sys.exit()
I can solve the problem if I make six loops, but if the length of the array changes I have to intervene on the source code. I'm looking for a recursive solution.
I would use the itertools.combinations API. You could also use a generator to allow finding all of the values, or choose to stop at the first:
import itertools
def find_comb_for_sum(data, total):
for i in range(len(data)):
for comb in itertools.combinations(data, i + 1):
if sum(comb) == total:
yield comb
This will find all combinations of the array starting from least amount of entries per combination to most. Reverse the range range(len(data))[::-1] if you'd like to do the opposite.
Some test cases:
arr = [50, 100, 100, 100, 200, 200]
inp = 450
comb = find_comb_for_sum(arr, inp)
print(f"Matching combination for {arr} summing to {inp} is: {next(comb, None)}")
arr = [50, 100, 100, 100, 200, 200]
inp = 444
comb = find_comb_for_sum(arr, inp)
print(f"Matching combination for {arr} summing to {inp} is: {next(comb, None)}")
Matching combination for [50, 100, 100, 100, 200, 200] summing to 450 is: (50, 200, 200)
Matching combination for [50, 100, 100, 100, 200, 200] summing to 444 is: None

What does "real" in pseudocode indicate?

I'm trying to translate this pseudocode and can't do it accurately. In particular, I can't seem to figure out what real here means. This is the pseudocode:
Function Real average(Real values[], Integer size)
Declare Real total = 0.0
Declare Integer counter = 0
While counter < size
Set total = total + values[counter]
Set counter = counter + 1
End While
Return total / size
End Function
Declare Real scores[6] = 90, 80, 70, 100, 60, 80
Display average(scores, 6)
And this is what I've come up with:
def average(values[], int(size))
total = 0.0
counter = 0
while counter < size:
total = total + values[counter]
counter = counter + 1
return total / size
scores[6] = 90, 80, 70, 100, 60, 80
print(average(scores, 6))
Some languages use the term "real" in place of "float" etc. Therefore, in Python, with this bit of code you can leave it out.
..but there are a few things wrong with your code other than that. For example you just want
scores=[90,80, 70, 100, 60, 80]
then just give average "scores" and 6
Like this
def average(values ,size):
total = 0.0
counter = 0
while counter < size:
total = total + values[counter]
counter = counter + 1
return total / size
scores = [90, 80, 70, 100, 60, 80]
print(average(scores, 6))
Whilst clearly it is not necessary to do this in this way, I presume you are just learning Python...

Debug Change finding using Memoization

From the last couple of hours, I have been trying to debug this code.
Problem: Given a set of coins: 1, 5, 10, 21 and 25 write an algorithm that finds change for a given amount using the minimum possible number of coins.
Ex: if the amount is 63, it should return 3 [21, 21, 21]
My Code:
def change_rec_memo(change_list, amount, memo):
if amount in change_list:
memo[amount] = (1, [amount])
return 1, [amount]
if amount in memo:
return memo[amount]
mini, values, min_coin = None, [], None
for coin in change_list:
if amount - coin > 0:
count, sub_values = change_rec_memo(change_list, amount-coin, memo)
if mini is None:
mini = count
values = sub_values
min_coin = coin
if count < mini:
mini = count
values = sub_values
min_coin = coin
values.append(min_coin)
memo[amount] = (mini+1, values)
return mini+1, values
def main():
print change_rec_memo([1, 5, 10, 21, 25], 52, {})
The code seems to work fine for most of the cases, but fails for cases like 52, 63. It outputs the correct number of coins but the coin_listing contains extra coins.
Here is a Python Fiddle for it: https://pyfiddle.io/fiddle/08b3da45-0c0d-464a-b025-00d215bc4634/?i=true
there is one more readable and shorter example.and use stack variable(the parameter of recursive function)
import sys
#functools.lru_cache()
def change_rec_memo(change_list, amount, count):
if amount == 0:
return count
if len(change_list) == 0 or amount < 0:return sys.maxsize
if amount - change_list[-1] >= 0:
return min(change_rec_memo(change_list,amount - change_list[-1], count +1),change_rec_memo(change_list[:-1], amount, count))
else:
return change_rec_memo(change_list[:-1], amount, count)
print(change_rec_memo((1, 5, 10, 21, 25), 215,0))

Calculate bankroll Martingale system

I want to write simple martingale system to count how much money will be there in "my" account after x spins on the roulette. The program is simple and just for experiment. So far I have this but, I want to add that if that random number a is for example two times or more... the same as d I would double my bet. So if.. a = 2 and a = 5 I would bet 4 instead of two and so on 8,16,32..
from random import*
money = 100
bet = 2
d = [0, 2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35]
for i in range(100):
a = randint(1, 36)
if a in d:
money -= bet
else:
money += bet
print("Your money",money,"€")
Keep a repeat variable, and use that to see if you got a in d consecutively.
from random import randint # Bad practice to import *
money = 100
bet = 2
# Consider revising the below to sets, which are faster for membership tests
d = [0, 2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35]
repeat = False
for _ in range(100): # You never use the loop variable, so denote that by naming it _
a = randint(1, 36) # btw, you have 0 in d but your randint starts from 1...
if a in d:
money -= bet
if repeat:
bet *= 2
repeat = True
else:
money += bet
repeat = False
print("Your money",money,"€")
You didn't specify what happens to the bet value when you lose a bet. The above simply keeps raising stakes if you win a bet consecutively. The bet value will not go down when you lose.
If you want to reset the bet value, you would just store that data in a separate variable like original_bet and reset with bet = original_bet within the else clause.

Print the sum of a list of integers without using sum()

I have a function defined below that prints each integer in the list, and it works perfectly. What I would like to do is create a second function that would call on or reutilize the int_list() function to display a sum of the list that's been generated.
I am not sure if that has been inherently performed by the code itself - I am rather new to the Python syntax.
integer_list = [5, 10, 15, 20, 25, 30, 35, 40, 45]
def int_list(self):
for n in integer_list
index = 0
index += n
print index
In your code, you're setting index=0 in every loop, so it should be initialized before the for loop:
def int_list(grades): #list is passed to the function
summ = 0
for n in grades:
summ += n
print summ
output:
int_list([5, 10, 15, 20, 25, 30, 35, 40, 45])
5
15
30
50
75
105
140
180
225
To get the sum of a list of integers you have a few choices. Obviously the easiest way is sum, but I guess you want to learn how to do it yourself. Another way is to store the sum as you add it up:
def sumlist(alist):
"""Get the sum of a list of numbers."""
total = 0 # start with zero
for val in alist: # iterate over each value in the list
# (ignore the indices – you don't need 'em)
total += val # add val to the running total
return total # when you've exhausted the list, return the grand total
A third option is reduce, which is a function that itself takes a function and applies it to the running total and each consecutive argument.
def add(x,y):
"""Return the sum of x and y. (Actually this does the same thing as int.__add__)"""
print '--> %d + %d =>' % (x,y) # Illustrate what reduce is actually doing.
return x + y
total = reduce(add, [0,2,4,6,8,10,12])
--> 0 + 2 =>
--> 2 + 4 =>
--> 6 + 6 =>
--> 12 + 8 =>
--> 20 + 10 =>
--> 30 + 12 =>
print total
42
integer_list = [5, 10, 15, 20, 25, 30, 35, 40, 45] #this is your list
x=0 #in python count start with 0
for y in integer_list: #use for loop to get count
x+=y #start to count 5 to 45
print (x) #sum of the list
print ((x)/(len(integer_list))) #average
list = [5, 10, 15, 20, 25, 30, 35, 40, 45]
#counter
count = 0
total = 0
for number in list:
count += 1
total += number
#don'n need indent
print(total)
print(count)
# average
average = total / count
print(average)
You can used reduce function from functools module
from functools import module
s=reduce(lambda x,y:x+y, integer_list)
output
225

Categories

Resources