Modify this Python program to generate only the subsets with odd sums? - python

I want it to take as input a set of numbers, such as [1,2,3,4], and only give the subsets with odd sums. For example, [1],[1,2],[2,3] etc.
I haven't tried much, I'm not sure where to start. Sorry, I'm very new to programming, but here's what I have so far. It generates all the possible subsets.
def rsubsets(s):
if len(s) == 0:
return [[]]
temp = rsubsets(s[1:])
new = []
for itm in temp:
new.append(itm)
n = len(new)
for j in range(n):
new[j] = new[j] + [s[0]]
return temp + new
Thanks.

Build upon your existing function:
def odd_subsets(s):
return [x for x in rsubsets(s) if sum(s) % 2 == 1]
Or without the comprehension:
def odd_subsets(s):
odd = []
for subset in rsubsets(s):
if sum(s) % 2 == 1:
odd.append(subset)
return odd

def odd_subsets(s):
lRet = []
for i in range(len(s)):
lRet.extend([c for c in itertools.combinations(s,i+1) if sum(c)%2==1])
return lRet
If you are dead set on using your initial function this is the easiest way to pull it off
def rsubsets(s):
def all_subsets(s):
if len(s) == 0:
return [[]]
temp = all_subsets(s[1:])
new = []
for itm in temp:
new.append(itm)
n = len(new)
for j in range(n):
new[j] = new[j] + [s[0]]
return temp + new
return [i for i in all_subsets(s) if sum(i)%2==1]
Pretty much what this does is call your initial recursive function and filter the results.
Another way is to use a flag...
def rsubsets(s,bFilter=True):
if len(s) == 0:
return [[]]
temp = rsubsets(s[1:],False)
new = []
for itm in temp:
new.append(itm)
n = len(new)
for j in range(n):
new[j] = new[j] + [s[0]]
if bFilter:
return [i for i in temp+new if sum(i)%2 ==1]
return temp + new

Related

Printing all combinations of balanced parenthesis - missing cases when the argument is larger than 4

I have been trying to tackle the problem in the title for some time now, and I have come up with the following code:
def parenthesize(lst, num):
if num == 1:
lst.append('()')
return lst
a1 = []
a2 = []
a = parenthesize(a1, num - 1)
b = parenthesize(a2, num - 1)
for i in range(len(a)):
a[i] = '(' + a[i] + ')'
for i in range(len(b)):
tmp = b[i]
b[i] = tmp + '()'
tmp = '()' + tmp
if tmp not in b:
b.append(tmp)
for i in a:
lst.append(i)
for i in b:
lst.append(i)
return lst
if __name__ == '__main__':
lst = []
n=5
res = parenthesize(lst, n)
print(res)
print(len(res))
Now, when n is equal to or larger than 5, I am missing some cases (e.g.: when n is 5, it prints 40 pairs instead of 42, and difference grows exponentially as n grows). I have been unable to realize why this is happening or which cases am I missing.
(I have a working solution from GfG, but I want to understand what I did wrong here).

Python why does my defined function which output is a list keep receiving nonetype error

I define a function which output is to print a list.
then i want to compare that list with len(l2) which is some other list in my code but i keep receiving this error that my defined function's output is a NoneType and it cant be compared with integers how can i solve this problem? Im new to programming so please answer simply
l = []
for i in range(0, 3):
x = int(input())
l.append(x)
def prime_counter(n):
b = 1
l1 = []
while b <= n:
k = 0
if n % b == 0:
j = 1
while j <= b:
if b % j == 0:
k = k + 1
j = j + 1
if k == 2:
l1.append(b)
b = b + 1
for i in range(0, len(l)):
l2 = []
if len(prime_counter(l[i])) > len(l2):
l2.extend(prime_counter(l[i]))
print(l2)
When you don't have any return statement in a function, None is returned automatically. So, you need to return some object from a function that the caller of the function can use further.
This is happening in your prime_counter function; you're supposed to return the l1 list from it but you're returning nothing warranting len(None) which would error out as None singleton does not have any length associated with it.
You need to return the l1 list from prime_counter:
def prime_counter(n):
b = 1
l1 = []
while b <= n:
...
...
return l1

Selection sort - python

I can't seem to make my selection sort work. Any idea whats wrong? When run it gives me [5,6,3,1]
Thx!
aList = [1,5,6,3]
def selection_sort( aList):
for i in range(len(aList)):
min = i
j = i + 1
for j in range(len(aList)):
if aList[j] < aList[min]:
min = j
swap(aList, min, i)
print(aList)
def swap(aList, x, y):
temp = aList[x]
aList[x] = aList[y]
aList[y] = temp
selection_sort(aList)
As I mentioned in the comment, it seemed to me that you used j = i + 1 in hopes that it will somehow effect the j in the subsequent loop, but it is a different variable. So is the aList in your function definition, it can have any name, even aList. Your j is iterating over the entire list again and again and hence the min or the smallest value is carried wherever i goes (so it ended up in the end). So what you need to do is make your second loop only iterate through the next items after i.
aList = [1,5,6,3]
def selection_sort(List):
for i in range(len(List)):
min = i
for k in range(i,len(List)):
if List[k] < List[min]:
min = k
swap(List, min, i)
print(List)
def swap(List, x, y):
temp = List[x]
List[x] = List[y]
List[y] = temp
selection_sort(aList)
def select_sort(l):
for i in range(len(l)):
min_loc = i
for j in range(i+1, len(l)):
if l[j] < l[min_loc]:
min_loc = j
l[min_loc],l[i] = l[i], l[min_loc]
return l

Recursive quicksort only returning result of first recursive call

I'm trying to implement quicksort in Python based on pseudocode I read in class but it does not sort the list. It does the recursion and always returns the result of the first recursive call (which is not sorted). Could anyone explain what I'm doing wrong?
def quick_sort(S):
n = len(S)
if n < 2:
return
p = S[0]
L = []
E = []
G = []
for i in range(0,len(S)):
if S[i] < p:
L.append(S[i])
elif p < S[i]:
G.append(S[i])
else:
E.append(S[i])
quick_sort(L)
quick_sort(G)
S=L+E+G
You don't return anything, you only create new lists, but don't use them.
Return the new list:
def quick_sort(S):
n = len(S)
if n < 2:
return S
p = S[0]
L = []
E = []
G = []
for v in S:
if v < p:
L.append(v)
elif p < v:
G.append(v)
else:
E.append(v)
return quick_sort(L) + E + quick_sort(G)
print quick_sort([6,4,2,3])

Recursive formula in python for recursive sigma how to?

I recently asked this question and got the first answer. I'm trying to put this into python code. This is what I have, but I keep getting 0 as the answer.
def f(n, k, s):
ans = 0
for j in range(1, min({k,s}) + 1):
print j
if (n == 1):
if (k >= s):
ans = ans + 1
elif (k < s):
ans = ans + 0
elif (s > n):
ans = ans + 0
elif (n*k < s):
ans = ans + 0
else:
ans = ans + f(n-1,j,s-j)
return ans
print f(10, 12, 70)
What is wrong with my code? What do I need to change? I don't know what's wrong. Please help. Thanks!
Your code is way too complex. You can write an almost one-to-one transcription of the answer you got on math exchange:
def f(n, k, s):
if n == 1:
return int(k >= s)
# or: 1 if k >=s else 0
return sum(f(n-1, j, s-j) for j in range(1, min(k, s)+1))
# to make it faster:
#return sum(f(n-1, j, s-j) for j in range(1, min(k, s)+1) if n*k >= s)
The problem in your code is that you put the base-case checking inside the loop, when it should be outside:
def f(n, k, s):
ans = 0
if n == 1:
return int(k >= s)
for j in range(1, min({k,s}) + 1):
print j
if n*k >= s:
ans += f(n-1,j,s-j)
return ans
With both implementations I get 12660 as result for f(10, 12, 70).
I don't know why yours doesn't work, but here's an implementation that does, which IMO is MUCH more readable:
from itertools import permutations
def f(n, k, s):
if k > s:
k = s-1
count = 0
sum_perms = []
number_list = []
for i in range(1,k):
for j in range(1,k,i):
number_list.append(i)
for perm in permutations(number_list, n):
if sum(perm) == s and perm not in sum_perms:
sum_perms.append(perm[:])
count += 1
return sum_perms, count
It's a lot slower than the recursion technique though :-(
itertools is amazing.

Categories

Resources