Number of sub sequences of length K having total sum S, given 2d array - python-3.x

I wish to find Number of sub sequences of length K having total sum S, given an array.
Sample Input:
a=[1,1,1,2,2] & K=2 & S=2
Sample Output:
3 {because a[0],a[1]; a[1]a[2]; a[0]a[2] are only three possible for the case}
I have tried to write a recursive loop in Python for starter but it isn't giving output as expected.Please can you help me find a loophole I might be missing on.
def rec(k, sum1, arr, i=0):
#print('k: '+str(k)+' '+'sum1: '+str(sum1)) #(1) BaseCase:
if(sum1==0 and k!=0): # Both sum(sum1) required and
return 0 # numbers from which sum is required(k)
if(k==0 and sum1 !=0): # should be simultaneously zero
return 0 # Then required subsequences are 1
if(k==0 and sum1==0 ): #
return 1 #
base_check = sum1!=0 or k!=0 #(2) if iterator i reaches final element
if(i==len(arr) and base_check): # in array we should return 0 if both k
return 0 # and sum1 aren't zero
# func rec for getting sum1 from k elements
if(sum1<arr[0]): # takes either first element or rejects it
ans=rec(k-1,sum1,arr[i+1:len(arr)],i+1) # so 2 cases in else loop
print(ans) # i is taken in as iterator to provide array
else: # input to rec func from 2nd element of array
ans=rec(k-1, sum1-arr[0], arr[i+1:len(arr)],i+1)+rec(k, sum1, arr[i+1:len(arr)],i+1)
#print('i: '+str(i)+' ans: '+str(ans))
return(ans)
a=[1,1,1,2,2]
print(rec(2,2,a))
I am still unable to process how to make changes. Once this normal recursive code is written I might go to DP approach accordinlgy.

Using itertools.combinations
Function itertools.combinations returns all the subsequences of a given lengths. Then we filter to keep only subsequences who sum up to the desired value.
import itertools
def countsubsum(a, k, s):
return sum(1 for c in itertools.combinations(a,k) if sum(c)==s)
Fixing your code
Your code looks pretty good, but there are two things that appear wrong about it.
What is this if for?
At first I was a bit confused about if(sum1<arr[0]):. I think you can (and should) always go to the else branch. After thinking about it some more, I understand you are trying to get rid of one of the two recursive calls if arr[0] is too large to be taken, which is smart, but this makes the assumption that all elements in the array are nonnegative. If the array is allowed to contain negative numbers, then you can include a large a[0] in the subsequence, and hope for a negative element to compensate. So if the array can contain negative numbers, you should get rid of this if/else and always execute the two recursive calls from the else branch.
You are slicing wrong
You maintain a variable i to remember where to start in the array; but you also slice the array. Pretty soon your indices become wrong. You should use slices, or use an index i, but not both.
# WRONG
ans=rec(k-1, sum1-arr[0], arr[i+1:len(arr)],i+1)+rec(k, sum1, arr[i+1:len(arr)],i+1)
# CORRECT
ans = rec(k-1, sum1-arr[i], arr, i+1) + rec(k, sum1, arr, i+1)
# CORRECT
ans = rec(k-1, sum1-arr[0], arr[1:]) + rec(k, sum1, arr[1:])
To understand why using both slicing and an index gives wrong results, run the following code:
def iter_array_wrong(a, i=0):
if (a):
print(i, a)
iter_array_wrong(a[i:], i+1)
def iter_array_index(a, i=0):
if i < len(a):
print(i, a)
iter_array_index(a, i+1)
def iter_array_slice(a):
if a:
print(a)
iter_array_slice(a[1:])
print('WRONG')
iter_array_wrong(list(range(10)))
print()
print('INDEX')
iter_array_index(list(range(10)))
print()
print('SLICE')
iter_array_slice(list(range(10)))
Also note that a[i:len(a)] is exactly equivalent to a[i:] and a[0:j] is equivalent to a[:j].
Clean version of the recursion
Recursively count the subsequences who use the first element of the array, and the subsequences who don't use the first element of the array, and add the two counts. To avoid explicitly slicing the array repeatedly, which is an expensive operation, we keep a variable start to remember we are only working on subarray a[start:].
def countsubsum(a, k, s, start=0):
if k == 0:
return (1 if s == 0 else 0)
elif start == len(a):
return 0
else:
using_first_element = countsubsum(a, k-1, s-a[start], start+1)
notusing_first_elem = countsubsum(a, k, s, start+1)
return using_first_element + notusing_first_elem

Related

I need the code to stop after break and it should not print max(b)

Rahul was learning about numbers in list. He came across one word ground of a number.
A ground of a number is defined as the number which is just smaller or equal to the number given to you.Hence he started solving some assignments related to it. He got struck in some questions. Your task is to help him.
O(n) time complexity
O(n) Auxilary space
Input Description:
First line contains two numbers ‘n’ denoting number of integers and ‘k’ whose ground is to be check. Next line contains n space separated numbers.
Output Description:
Print the index of val.Print -1 if equal or near exqual number
Sample Input :
7 3
1 2 3 4 5 6 7
Sample Output :
2
`
n,k = 7,3
a= [1,2,3,4,5,6,7]
b=[]
for i in range(n):
if k==a[i]:
print(i)
break
elif a[i]<k:
b.append(i)
print(max(b))
`
I've found a solution, you can pour in if you've any different views
n,k = 7,12
a= [1,2,3,4,5,6,7]
b=[]
for i in range(n):
if k==a[i]:
print(i)
break
elif a[i]<k:
b.append(i)
else:
print(max(b))
From what I understand, these are the conditions to your question,
If can find number, print the number and break
If cannot find number, get the last index IF it's less than value k
Firstly, it's unsafe to manually input the length of iteration for your list, do it like this:
k = 3
a= [1,7,2,2,5,1,7]
finalindex = 0
for i, val in enumerate(a):
if val==k:
finalindex = i #+1 to index because loop will end prematurely
break
elif val>=k:
continue
finalindex = i #skip this if value not more or equal to k
print(finalindex) #this will either be the index of value found OR if not found,
#it will be the latest index which value lesser than k
Basically, you don't need to print twice. because it's mutually exclusive. Either you find the value, print the index or if you don't find it you print the latest index that is lesser than K. You don't need max() because the index only increases, and the latest index would already be your max value.
Another thing that I notice, if you use your else statement like in your answer, if you have two elements in your list that are larger than value K, you will be printing max() twice. It's redundant
else:
print(max(b))

What can I do to add a list and sort out all the prime numbers in the list? Python 3

I am creating a program that
accepts an inputted list
finds all the prime numbers and only displays them.
I tried many different methods, many derived from existing prime filters, but they have hardcoded lists rather user-inputted ones.
I just can't seem to get a filter working with inputting a list, then filtering the prime numbers.
my_list = input("Please type a list")
list(my_list)
prime=[]
for i in my_list:
c=0
for j in range(1,i):
if i%j==0:
c+=1
if c==1:
prime.append(i)
return (prime)
When you get input, you're getting a string. You can't cast a string to a list immediately. Maybe you can request the user to use a separator between the numbers then use split method and cast strings to integers like this:
my_list = input("Please enter the list of numbers and use space seperator")
s_list = my_list.split()
cast_list = [int(num) for num in s_list]
Then, you can work on your prime number task based on your preferred algorithm.
Not sure what your c variable is for, current_number? Your loop returns 'str' object cannot be interpreted as an integer for me. I have used len(my_list) to get the length for the loop.
range() defines as range(start, stop, step) - learn more - it accepts integers and parameters are partially optional.
I copied the code from https://www.codegrepper.com/code-examples/python/how+to+find+prime+numbers+in+list+python
my_list = input("Please type a list")
primes = []
for i in range(0, len(my_list)):
for j in range(2, int(i ** 0.5) + 1):
if i%j == 0:
break
else:
primes.append(i)
print(primes)
More helpful resources from SO: Python function for prime number
I hope this helps.

My second for loop is not working in the below code

nums=[0,5,4,12]
n=len(nums)
temp=1
ans=[]
for i in range(n):
ans.append(temp)
temp*=nums[i]
temp=1
for i in range(n-1,-1):
ans[i]*=temp
temp*=nums[i]
print("yes")
print(ans)
Given an integer array nums, return an array answer such that answer[i] is equal to the product of all the elements of nums except nums[i].
The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer.
You must write an algorithm that runs in O(n) time and without using the division operation.
This is a solution for this leetcode question but my second for loop is not executing, and i don't know why.
Using range like this will result in zero iterations because the "step" parameter is 1. So because it is 1 it will think it should go upwards, but n is already above -1, so it should be like
range(n, -1, -1)
also you most probably want
import math
n = [0, 5, 4, 12]
ans = []
for num in n:
temp = n[:] # create a copy
temp.remove(num) # remove the number you are on
ans.append(math.prod(temp)) # use math.prod to multiply the rest together
return ans

choose one list. choose the one whose nth element is the smallest. Python 3

I have two lists. I have to choose one. I have to choose the one with the smallest nth element. So I can choose the smallest element easy with min, but how do I back track it to the list itself. Have literally no idea how to solve this presumably easy problem.
a = [2,45,1,56]
b= [0,23,3,87]
Which list has the smallest element at position 2? The answer here is list a.
In case I wasnt clear, the program sould be able to solve this task for any pair of lists.
Here is a very simple snippet that does what you want, but you might want to check for the size of the arrays, in case the index is out of range.
def choose_smallest(a, b, i):
if len(a) >= i or len(b) >= i:
return 0 # do whatever you want here
if a[i] < b[i]:
return a
else:
return b
Also notice that both nth elements in your array can have the exact same value... In this example array b will be returned, but you can change that behaviour if needed.
EDIT
Added array length check
According to your example, here is a sample code you can try. You can change the code as per your requirement.
a = [2,45,1,56]
b = [0,23,3,87]
n= int(input('Enter element number: ')) # n starts from zero to length of list - 1
if a[n] > b[n]:
print('List b has smaller nth element')
elif a[n] < b[n]:
print('List a has smaller nth element')
else:
print('Both lists have equal nth element')

Not showing output python, no error showing

Let us consider polynomials in a single variable x with integer coefficients: for instance, 3x^4 - 17x^2 - 3x + 5. Each term of the polynomial can be represented as a pair of integers (coefficient,exponent). The polynomial itself is then a list of such pairs.
We have the following constraints to guarantee that each polynomial has a unique representation:
Terms are sorted in descending order of exponent
No term has a zero coefficient
No two terms have the same exponent
Exponents are always nonnegative
For example, the polynomial introduced earlier is represented as
[(3,4),(-17,2),(-3,1),(5,0)]
The zero polynomial, 0, is represented as the empty list [], since it has no terms with nonzero coefficients.
Write Python functions for the following operations:
addpoly(p1,p2) ?
def addpoly(p1,p2):
p1=[]
p2=[]
for i in range(0,len(p1)):
for j in range(0,len(p2)):
L=[]
if p1[i][1]==p2[j][1]:
L=L[p1[i][0]+p2[j][0]][p1[i][1]]
elif p1[i][1]!=p2[j][1]:
L=L+p1[i][j]
L=L+p2[i][j]
print("L")
You are reassigning the p1 and p2 arguments to empty lists at the top of your function. This means you will always be checking for i in range(0, 0), which is an empty range. In other words, nothing in your loop will be executed. This is why you are not seeing any output. You are not seeing any error messages, because there is nothing wrong with your syntax, the problem is with the logic.
My math skills are nonexistent, so I cannot comment on the accuracy of most of the logic in your code, but for sure you need to get rid of the first two lines of your function (p1 = [] and p2 = []) or your function will do nothing.
Also, make sure to print the variable L rather than the string "L" to print your list:
print(L)
try this code
def addpoly(p1,p2):
L=[]
for i in range(0,len(p1)):
for j in range(0,len(p2)):
if p1[i][1] == p2[j][1] and p1[i][0]+p2[j][0] != 0 :
L.append((p1[i][0]+p2[j][0],p1[i][1]))
elif p1[i][1] == p2[j][1] and p1[i][0]+p2[j][0] == 0 :
pass
elif i == j:
L.append(p2[i])
L.append(p1[i])
return (L)

Resources