I was trying to solve a dp problem (checking if given amount can be broken down with given coins with different values, assuming there are infinite number of coins available for each valued coins)
def istrue(coins, amount):
if (amount - coins[0] > 0):
holder = False
while (holder == False and len(coins) != 0):
holder = holder or istrue(coins, amount - coins[0])
if(len(coins) != 0):
coins.pop(0)
return holder
elif (amount - coins[0] < 0):
return False
else:
return True
And was not sure what would be an appropriate way of iterating through the given coins.
Currently, I am having trouble inside the while loop. (If the amount left to break down is bigger than current value of a coin, it moves onto the next coin) But the amount to be break down also goes back a step because I used pop..
Any hints for fixing this? example) coins: [7,3]. amount: 20. -> as it reaches 6 (20-7-7), the index for coins array moves on but also the amount gets backed up a step because I pop()ed it.
You can loop over your coins instead of doing a recursion:
def istrue(coins, amount):
coins.sort(reverse=True)
_, remainder = divmod(amount, coins[0])
coins.pop(0)
for coin in coins:
_, remainder = divmod(remainder, coin)
return not remainder
Related
Given a positive integer change, a set of coins makes change for change if the sum of the values of the coins is change. We will use standard US Coin values: 1, 5, 10, 25.
I was asked to solve this coin change question with recursion function only(while and for loop are not allowed), and I am very struggling with it. Please help!
def next_smaller_coin(coin):
"""Returns the next smaller coin in order."""
if coin = 25:
return 10
elif coin = 10:
return 5
elif coin = 5:
return 1
def count_coins(change):
if change == 0:
return 1
elif change < 0:
return 0
else:
with_coin = count_coins(change - next_smaller_coin(coins))
wo_coin = count_coins(change)
return with_coin + wo_coin
I'm doing a little program. This program works as follows:
1- U put how many coins do u want to have
2- U put all of them 'heads'
3- From the second coin, you start to flip the coins that the index a multiple of 2, when u finish you go back to the start and start again, but this time you'll start from the third coin and flip all that the index is multiple of 3, and continue like that, restart from the fourth coin and flip the multiples of 4 and continue until the end...
Example: 4 coins-->
heads, heads,heads,heads
1° time:
heads,talls,heads,talls,
2° time:
heads,talls,talls,talls,
3° time:
heads, talls,talls,heads.
I think this code is almost reaching it, but this function I built doesn't do the job of flipping the coin and change the 'mode' on the 'moedas' list
Vocab: Heads-cara / Talls - coroa /Coin(s)- moeda(s) /To flip - Virar (portuguese)
I'll apreciate any help to change some error on the rest of the code too.
def Virar(moeda):
if moeda == 'cara':
moeda = 'coroa'
if moeda == 'coroa':
moeda = 'cara'
return moeda
qtde_moedas = int(input('How much coins do u want?'))
moedas=[]
while (len(moedas))<qtde_moedas:
moedas.append('cara')
for divisor in range(2,len(moedas)):
for index_num in range(len(moedas)):
if (index_num+1)%divisor==0:
moedas[index_num] = Virar(moedas[index_num])
else:
pass
Say you pass 'cara' to your function Virar; first it changes moeda to 'coroa', because it was 'cara'. And then, it checks whether moeda is 'coroa', which is True now, so it turns it back to 'cara'! So Viara never flips the coin as you wish. Instead, try using elif or else:
def Virar(moeda):
if moeda == 'cara':
moeda = 'coroa'
else:
moeda = 'cara'
return moeda
A shorter version, if you are interested, would be the following:
def virar(moeda):
return 'coroa' if moeda == 'cara' else 'cara'
qtde_moedas = int(input("How many coins do you want? "))
moedas = ['cara'] * qtde_moedas
for divisor in range(2, qtde_moedas + 1):
for i in range(divisor - 1, qtde_moedas, divisor):
moedas[i] = virar(moedas[i])
print(moedas)
I am now working on the Leetcode 322. Coin Change, the question is as following:
You are given an integer array coins representing coins of different
denominations and an integer amount representing a total amount of
money.
Return the fewest number of coins that you need to make up that
amount. If that amount of money cannot be made up by any combination
of the coins, return -1.
You may assume that you have an infinite number of each kind of coin.
Example 1:
Input: coins = [1,2,5], amount = 11 Output: 3 Explanation: 11 = 5 + 5 + 1
Example 2:
Input: coins = [2], amount = 3 Output: -1
Example 3:
Input: coins = [1], amount = 0 Output: 0
Example 4:
Input: coins = [1], amount = 1 Output: 1
Example 5:
Input: coins = [1], amount = 2 Output: 2
I tried to solve it via the top-down DP with memorization. I set a parameter in the helper function to remember the count.
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
c = set(coins)
dp = [0] * (amount + 1)
def helper(a, count):
if a == 0:
return count
# if a in c:
# return 1 + count
if dp[a] != 0:
return dp[a]
res = math.inf
for coin in c:
if a - coin >= 0 and helper(a-coin, count+1) != -1:
res = min(res, helper(a-coin, count+1))
dp[a] = res if res < math.inf else -1
return dp[a]
return helper(amount, 0)
But it won't pass the case as:
[1,2,5]
100
The result supposes to be 20, but I got 92.
I tried to figure it out the whole afternoon, but not sure where I did wrong. I hope you can give me some suggestion where I went wrong.
Thanks in advance for your help.
!!! THIS IS A COMPLETE SOLUTION !!!
Ok, so here is my solution to this problem (idea explained below):
def solve(lst, amount):
lst = sorted(lst, key=lambda x: x, reverse=True)
cases = []
for seq in [lst[i:] for i in range(len(lst))]:
current_amount = 0
count = 0
for item in seq:
while True:
if current_amount + item == amount:
count += 1
current_amount += item
break
elif current_amount + item > amount:
break
elif current_amount < amount:
count += 1
current_amount += item
if current_amount == amount:
break
if current_amount == amount:
cases.append(count)
if cases:
return min(cases)
return -1
print(solve([1, 2, 5], 100))
print(solve([1, 5, 7, 9], 12))
# 20
# 2
Explanation:
!!! MAIN IDEA
First You have to start with the largest number in the list because it takes the least amount of additions to come the closest or completely become the final amount.
!!!
EDIT
As suggested by #nitinkumarp in comments, previous version (can check edits but why?) failed in some cases as mentioned in the comment, a workaround for that issue is to check all sequences in order, still using the greedy approach but slicing the original list shorter and shorter so that it can also check the correct solution which is 7 + 5, which is 2 coins.
So first thing to do is sort the list from the largest to the smallest number as shown with .sort() function.
Then for each number in that list (for loop starts with the first item in the list so the largest number) put them in a while True loop so that they keep adding to the total until condition is met:
There are 3 conditions:
current amount (from all the additions) plus the current item in the list equals the final amount, in that case increase the count by one and add the current item to total and then break out of the loop
if the current amount + current item in list are bigger than the final amount just break out (this makes sure that no more of such number are added)
the one that will get used the most is the one that checks if the current amount is smaller than the final one, but it is important that they are elif statements because in that case if one statement turns out to be true it doesn't check the rest which is not needed in this case because otherwise it would turn out to be true even if You couldn't add more to the current amount to not exceed the final amount.
this if statement is outside of the while True loop and checks if the final amount is matched when a number 'breaks out' of the while True loop, this is to prevent continuous checking even tho the result would be already achieved.
Then the result get evaluated and if the current amount doesn't match the final print -1 else print the count
This is my solution.
The main idea is to make use of the max value element in the list as much as possible and when it becomes dysfunctional, it is about to remove it from the list and use the new max value element.
class Solution:
def coinChange(self, coins, amount):
result = []
new_amount = amount
while len(coins) > 0:
while new_amount >= max(coins):
new_amount -= max(coins)
result.append(max(coins))
coins.remove(max(coins))
if len(result) == 0:
return 0
if sum(result) != amount:
return -1
return len(result)
Let's test the results;
coins = [2, 5, 4, 1]
amount = 10
s = Solution()
print(s.coinChange(coins=coins, amount=amount))
Output: 2
Because it produced a result list like this; [5, 5]
Trying to [solve] the problem in leetcode (322):
You are given coins of different denominations and a total amount of
money amount. Write a function to compute the fewest number of coins
that you need to make up that amount. If that amount of money cannot
be made up by any combination of the coins, return -1.
I am stuck in this input: coins = [2] and target = 3
I wonder why it is returning 0? I debugged this but not able to figure out.
class Solution(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
def get_cost(coins, amount):
if amount == 0:
return 0
min_cost = float('inf')
for coin in coins:
if amount >= coin:
min_cost = min(min_cost, 1 + self.coinChange(coins, amount - coin))
return min_cost
cost = get_cost(coins, amount)
if cost == float('inf'):
return -1
return cost
Your logic is not correct, you want to do something like this: the minimum cost either contains the current coin or it does not. This would in pseudo code look like:
min_coins = current cost + min(cost without using this coin, cost using this coin)
so you should put the current cost in your state and also keep track of which coins you are allowed to use.
I am trying to put together a simple program which could work out n prime numbers. I would like to do this by using a nested for loop, where one would go through the numbers, and another would divide that number by all of the numbers up to it to see if it would be divisible by anything.
The problem I am having is that in the main for loop, I need to start it at 2, seeing as 1 would mess up the system and I don't want it to be considered a prime. For the loop to have a starting number however, it also needs an ending number which is difficult in this instance as it is hard to generate the largest prime that will be needed prior to the loop working.
Here's the program that I am using right now. Where I have marked X is where I need to somehow put an ending number for the For Loop. I guess it would be much simpler if I let the For Loop be completely open, and simply take out anything that '1' would produce in the loop itself, but this feels like cheating and I want to do it right.
check = 0
limit = int(input("Enter the amount of Prime Numbers"))
for i in range(2,X):
check = 0
if i > 1:
for j in range(2,i):
if (i % j) == 0:
check = 1
if check == 0:
print (i)
Thanks for your help!
You can step through an unlimited amount of numbers using a generator object.
Insert the following somewhere near the top of your code:
def infinite_number_generator(initial_value=2):
""" Generates an infinite amount of numbers """
i = initial_value
while True:
yield i
i += 1
What this does is it creates a function for constructing generator objects that "pause" whenever they reach the yield statement to "yield" whatever value is specified by the yield command, and then continue to execute from the next line beneath the yield statement.
Python's own range function is itself an example of a generator, and is roughly equivalent to (ignoring the step argument and other peculiarities)
def range(start, end):
i = start
while i < end:
yield i
i += 1
So your program would then look like this:
def infinite_number_generator(initial_value=2):
""" Generates an infinite amount of numbers """
i = initial_value
while True:
yield i
i += 1
check = 0
limit = int(input("Enter the amount of Prime Numbers"))
for i in infinite_number_generator():
check = 0
for j in range(2,i):
if (i % j) == 0:
check = 1
if check == 0:
print (i)
if i == limit:
break
I should also point out that the code you provided is buggy - it will never stop printing because there's no checking whether you've found your limit number of primes yet or not.
This should do what you want.
check = 0
limit = int(input("Enter the amount of Prime Numbers"))
counter = 0
i = 2
while counter < limit:
check = 0
if i > 1:
for j in range(2,i):
if (i % j) == 0:
check = 1
if check == 0:
counter += 1
print (i)
i += 1
In your code you start i with 2 and always increment by 1, so the i will always remain greater than 1, therefore the test if i > 1 is useless.
For efficiency you can stop the check at the square of i or i/2 (no divisors in [i/2 + 1, i[ ).
you can update your code as follow:
n = int(input("Enter the amount of Prime Numbers: "))
FoundPrimes = 0
i = 2
while FoundPrimes < n:
isPrime = True
for j in range(2,1 + i//2):
if (i % j) == 0:
isPrime = False
if isPrime:
FoundPrimes += 1
print(i, end = '\t')
i += 1