Implementing Coin Changing Prob using Niave method - python

I'm trying to implement Coin Changing Problem which states that
Coin Changing problem is described as given a value N, if we want to
make change for N cents, and we have infinite supply of each of S =
{S1, S2, . . . , Sm} valued coins, how many ways can we make the
change? The order of coins doesn’t matter. Identify all possible ways
of changing N cent by Greedy Method. For example, for N = 4 and S =
{1, 2, 3}, there are four solutions: {1, 1, 1, 1}, {1, 1, 2}, {2, 2},
{1, 3}. So output should be 4. For N = 10 and S = {2, 5, 3, 6}, there
are five solutions: {2, 2, 2, 2, 2}, {2, 2, 3, 3}, {2, 2, 6}, {2, 3,
5}and{5, 5}. So the output should be 5.
Note: This not the original Coin changing problem where we have to find the optimal solution (i.e. Minimum No. of coins)
In my below python implementation, I'm using a list name called $check$. Problem is that the program is using same $check$ list throughout its run time and hence I'm getting wrong result. It should use the $check$ list which is local to its function call. Can anybody find a way out of this..
# N
N = 10
# Set of Changes
s = [2, 3, 5, 6]
lst = []
check = [0, 0, 0, 0]
def Coin_Change_Count(C, check):
for k in range(len(s)):
i = len(s) - k - 1
t = C - s[i]
if (t >= 0):
if (s[i] == 2):
check[0] += 1
elif (s[i] == 3):
check[1] += 1
elif (s[i] == 5):
check[2] += 1
elif (s[i] == 6):
check[3] += 1
if (t >= s[0]):
Coin_Change_Count(t, check)
if (t == 0):
if (not (check in lst)):
lst.append(check)
Coin_Change_Count(N, check)
print(len(lst))

Related

Doing a 2sum algorithm and I'm confused on python syntax

so I followed a tutorial to learn how to complete 2 sum and I understand what ever line means but I dont understand why diffs[list[i]] returns the 0 index. I went through the the algorithm with the current arguments and i comes out to 3 when it returns the indexes
diffs = {} # Make a hash map to store values
for i in range(len(list)): # Iterate through list
if list[i] in diffs: # If the number you are on is in the has map
return [diffs[list[i]], i] # return indexes
else:
diffs[target - list[i]] = i
print(twosum([2, 11, 15, 7], 9))
def twosum(nums, target):
diffs = {} # Make a hash map to store values
for i in range(len(nums)): # Iterate through list
if nums[i] in diffs: # If the number you are on is in the has map
return [diffs[nums[i]], i] # return indexes
else:
diffs[target - nums[i]] = i
print(i, diffs)
In [4]: print(twosum([2, 11, 15, 7], 9))
0 {7: 0}
1 {7: 0, -2: 1}
2 {7: 0, -2: 1, -6: 2}
[0, 3]
As you can see from the above output, 7 has index 0 in the dictionary. It's the first element that is added to the dictionary. The reason is that you are saving the differences in the dictionary. target - nums[0] is 7 in this case because nums[0] is 2.
Then, when you reach the last element, namely 7, you find it in the dictionary with the index 0. That is diffs[nums[3]] == diffs[7] == 0. And you return [diffs[nums[i]], i] == [diffs[nums[3]], 3] == [diffs[7], 3] == [0, 3].
Also, don't use the name list to name your variables.
On the first run of the loop. diffs[target - list[i]] = i sets diffs to {7: 0}. That's how diffs[list[3]] evaluates to 0. Eg.
diffs[list[3]]
diffs[7]
0

Loop inside the function can't run as well as an outside loop

I tried to find all the duplicates in list by the loop like the following
num = [1, 2, 2, 1]
for i in range(1, len(num)):
if num[i] == num[i - 1]:
print(num[i])
and it return all the duplicates inside the list but when i pass that inside the the function it only pick the first like the following
def FindDuplicates(nums):
nums.sort()
for i in range(1, len(nums)):
if nums[i] == nums[i - 1]:
return nums[i]
and this function remove the duplicates but can't work well as i expected
means when list looks like this print(RemoveDuplicate([1, 2, 3, 4, 4, 5, 6]))
it work well but this print(RemoveDuplicate([1, 2, 3, 4, 4, 4, 5, 6, 6, 6]))
the function crush
def RemoveDuplicate(array):
no_double = []
its_index = 0
founded = 0
for arr in array:
if array.count(arr) > 1:
founded = arr
its_index = array.index(arr)
elif array.count(arr) <= 1:
no_double.append(arr)
no_double.insert(its_index, founded)
return no_double
when there is a lot of duplicates this function can't pick them all out
any one who can help me to fix this bug
Try this :)
from collections import Counter
lst = [4,3,2,4,5,6,4,7,6,8]
d = Counter(lst) # -> Counter({4: 3, 6: 2, 3: 1, 2: 1, 5: 1, 7: 1, 8: 1})
res = [k for k, v in d.items() if v > 1]
print(res)
Can anyone help me to fix this bug?
Doing it your way, maybe this:
def FindDuplicates(nums):
d = []
nums.sort()
for i in range(1, len(nums)):
if nums[i] == nums[i - 1]:
d.append(nums[i])
return d
The reason yours don't work is because when the program reaches a return statement in a function, it will jump out of the function right then and there. So if you want to returns multiple values in a single function, make sure they're returned all at once.

Check if values in list exceed threshold a certain amount of times and return index of first exceedance

I am searching for a clean and pythonic way of checking if the contents of a list are greater than a given number (first threshold) for a certain number of times (second threshold). If both statements are true, I want to return the index of the first value which exceeds the given threshold.
Example:
# Set first and second threshold
thr1 = 4
thr2 = 5
# Example 1: Both thresholds exceeded, looking for index (3)
list1 = [1, 1, 1, 5, 1, 6, 7, 3, 6, 8]
# Example 2: Only threshold 1 is exceeded, no index return needed
list2 = [1, 1, 6, 1, 1, 1, 2, 1, 1, 1]
I don't know if it's considered pythonic to abuse the fact that booleans are ints but I like doing like this
def check(l, thr1, thr2):
c = [n > thr1 for n in l]
if sum(c) >= thr2:
return c.index(1)
Try this:
def check_list(testlist)
overages = [x for x in testlist if x > thr1]
if len(overages) >= thr2:
return testlist.index(overages[0])
# This return is not needed. Removing it will not change
# the outcome of the function.
return None
This uses the fact that you can use if statements in list comprehensions to ignore non-important values.
As mentioned by Chris_Rands in the comments, the return None is unnecessary. Removing it will not change the result of the function.
If you are looking for a one-liner (or almost)
a = filter(lambda z: z is not None, map(lambda (i, elem) : i if elem>=thr1 else None, enumerate(list1)))
print a[0] if len(a) >= thr2 else false
A naive and straightforward approach would be to iterate over the list counting the number of items greater than the first threshold and returning the index of the first match if the count exceeds the second threshold:
def answer(l, thr1, thr2):
count = 0
first_index = None
for index, item in enumerate(l):
if item > thr1:
count += 1
if not first_index:
first_index = index
if count >= thr2: # TODO: check if ">" is required instead
return first_index
thr1 = 4
thr2 = 5
list1 = [1, 1, 1, 5, 1, 6, 7, 3, 6, 8]
list2 = [1, 1, 6, 1, 1, 1, 2, 1, 1, 1]
print(answer(list1, thr1, thr2)) # prints 3
print(answer(list2, thr1, thr2)) # prints None
This is probably not quite pythonic though, but this solution has couple of advantages - we keep the index of the first match only and have an early exit out of the loop if we hit the second threshold.
In other words, we have O(k) in the best case and O(n) in the worst case, where k is the number of items before reaching the second threshold; n is the total number of items in the input list.
I don't know if I'd call it clean or pythonic, but this should work
def get_index(list1, thr1, thr2):
cnt = 0
first_element = 0
for i in list1:
if i > thr1:
cnt += 1
if first_element == 0:
first_element = i
if cnt > thr2:
return list1.index(first_element)
else:
return "criteria not met"
thr1 = 4
thr2 = 5
list1 = [1, 1, 1, 5, 1, 6, 7, 3, 6, 8]
list2 = [1, 1, 6, 1, 1, 1, 2, 1, 1, 1]
def func(lst)
res = [ i for i,j in enumerate(lst) if j > thr1]
return len(res)>=thr2 and res[0]
Output:
func(list1)
3
func(list2)
false

Using the Counter function on a list in python

We have to return the frequency of the length of words in a .txt file.
E.g "My name is Emily" will be converted to a list: ["My", "name", "is", "Emily"], which I converted to a list of the lengths of each word: [2, 4, 2, 5] and then I use the function Counter which outputs a dictionary that looks like:
Counter({2: 2, 4: 1, 5: 1})
But I need it to include count of zero:
Counter({1: 0, 2: 2, 3: 0, 4: 1, 5: 1})
Any ideas?
Should I get rid of the Counter function all together?
Counter only counts the frequency of items, which means that it keeps the count of items which are present.
But, if the item you looking for is not there in the Counter object, it will return 0 by default.
For example,
print Counter()[1]
# 0
If you really need the items with zero count in it, then you can create a normal dictionary out of a Counter, like this
c = Counter({2: 2, 4: 1, 5: 1})
print {num:c[num] for num in xrange(1, max(c) + 1)}
# {1: 0, 2: 2, 3: 0, 4: 1, 5: 1}
Using the Counter class from the collections module it is indeed implicit:
txt = "My name is Emily"
d = collections.Counter([len(x) for x in txt.split()])
d variable contains the information you mentioned without the number 1:
Counter({2: 2, 4: 1, 5: 1})
d[1] returns 0

How to return the number of characters whose frequency is above a threshold

How do I print the number of upper case characters whose frequency is above a threshold (in the tutorial)?
The homework question is:
Your task is to write a function which takes as input a single non-negative number and returns (not print) the number of characters in the tally whose count is strictly greater than the argument of the function. Your function should be called freq_threshold.
My answer is:
mobyDick = "Blah blah A B C A RE."
def freq_threshold(threshold):
tally = {}
for char in mobyDick:
if char in tally:
tally[char] += 1
else:
tally[char] = 1
for key in tally.keys():
if key.isupper():
print tally[key],tally.keys
if threshold>tally[key]:return threshold
else:return tally[key]
It doesn't work, but I don't know where it is wrong.
Your task is to return number of characters that satisfy the condition. You're trying to return count of occurrences of some character. Try this:
result = 0
for key in tally.keys():
if key.isupper() and tally[key] > threshold:
result += 1
return result
You can make this code more pythonic. I wrote it this way to make it more clear.
The part where you tally up the number of each character is fine:
>>> pprint.pprint ( tally )
{' ': 5,
'.': 1,
'A': 2,
'B': 2,
'C': 1,
'E': 1,
'R': 1,
'a': 2,
'b': 1,
'h': 2,
'l': 2,
'\x80': 2,
'\xe3': 1}
The error is in how you are summarising the tally.
Your assignment asked you to print the number of characters occurring more than n times in the string.
What you are returning is either n or the number of times one particular character occurred.
You instead need to step through your tally of characters and character counts, and count how many characters have frequencies exceeding n.
Do not reinvent the wheel, but use a counter object, e.g.:
>>> from collections import Counter
>>> mobyDick = "Blah blah A B C A RE."
>>> c = Counter(mobyDick)
>>> c
Counter({' ': 6, 'a': 2, 'B': 2, 'h': 2, 'l': 2, 'A': 2, 'C': 1, 'E': 1, '.': 1, 'b': 1, 'R': 1})
from collections import Counter
def freq_threshold(s, n):
cnt = Counter(s)
return [i for i in cnt if cnt[i]>n and i.isupper()]
To reinvent the wheel:
def freq_threshold(s, n):
d = {}
for i in s:
d[i] = d.get(i, 0)+1
return [i for i in d if d[i]>n and i.isupper()]

Categories