Even though it looks not difficult, it makes me crazy.
I couldn't even get close to an answer.
Can you guys give me any help?
Write a recursive function sums_to(nums, k) that takes a list of integers and returns True if the
sum of all the elements in the list is equal to k and returns Falseotherwise.
Example:
>>> nums = [1, 2, 3]
>>> sums_to(nums, 6)
True
>>> sums_to(nums, 5)
False
>>> sums_to([], 1)
False
Note: You are not allowed to use any python sum function in any form, nor sum the list and then at
the end check whether it equals k. In addition, you must write sums_to as a single recursive function:
That is, you may not use a main function and a recursive helper function.
# my pool code
def sums_to(nums, k):
if nums == []:
return False
if nums[0] + sums_to(nums[1:], k) == k:
return True
This is what I tried so far.
Sadly, I could not think of a hint to give. The whole problem is about that return statement:
def sums_to(nums, k):
if not nums:
return k == 0
return sums_to(nums[:-1], k - nums[-1])
print(sums_to([1, 2, 3], 6))
print(sums_to([1, 2, 3], 5))
print(sums_to([], 1))
You can do this using recursion, you have two case, if the list is empty, or not:
def sums_to(nums , n):
if len(nums) == 0:
return n == 0
else:
m = nums[0]
nums.pop(0)
return sums_to(nums, (n-m))
print(sums_to([2,3], 5))
Related
I need to write a Python program that determines whether a given integer input is is a twin prime number or not. If the input number is a twin prime, the program must output true. Otherwise, it must output false.
Please may someone guide me with how this program should be written in Python?
This is what I have done so far. I am stuck at the is_twin_prime function part.
def is_prime(x):
for i in range(2, x):
if x % i == 0:
return False
return True
def is_twin_prime(x):
if is_prime(x) = True:
N = int(input())
for i in range(N):
p = int(input())
if is_twin_prime(p):
print("true")
else:
print("false")
Based on the assumption, that you are trying to determine if N & p are twin primes of one another, I found several issues with your code as follows:
the is_twin_prime function has no False return
the is_prime function always starts with 2 and iteratively checks for prime, this is very inefficient.
To provide an answer, I started with the following factoids about twin_primes:
both numbers must be prime
abs(n-p) == 2
n and p must each have a units digit in [0, 2, 3, 5, 7, 8]
To make the function testing for twin primes as efficient as possible, I eliminated any numbers not meeting the last two cases first, and only if necessary did I generate a list of primes. Also, when generating the primes, I only did it once for the largest number since, once I have the list or the largest both numbers must be in the list.
To make searching for primes more efficient I employed itertools, although this could be done with slightly less efficiency without it's use.
import itertools
def erat2():
D = { }
yield 2
for q in itertools.islice(itertools.count(3), 0, None, 2):
p = D.pop(q, None)
if p is None:
D[q*q] = q
yield q
else:
x = p + q
while x in D or not (x&1):
x += p
D[x] = p
def generatePrimes(given_number):
"""
Returns the prime number <= given_number using
an adaptive sieve of estraothenes approach
"""
return list(itertools.islice(erat2(), given_number))
def is_twinPrime(n, p):
accepted_digits = [0, 2, 3, 5, 7, 8]
if abs(n-p) != 2:
return False
elif n%10 not in accepted_digits and p%10 not in accepted_digits:
return False
else:
primes = generatePrimes(max(n, p))
if n in primes and p in primes:
return True
return False
N = int(input("Enter first number"))
P = int(input(Enter second number"))
print(istwinPrime(N, P)
How would we adapt it to return True if at least three of the numbers are odd? Short-circuit the traversal when
the third odd number is found — don’t traverse the whole list unless we have to.
****I am a novice in python, I want to know the time is taken more when I use ==,<= operators why? did this code stop traversing after find the 3 odd?****
import time
start_time = time.time()
def d(x):
count = 0
for num in x:
if num % 2 != 0:
count += 1
if count <= 3:
return True
return False
print((time.time() - start_time))
f = d([1,2,4,6,8,7,3,11,16,88,66,44,22])
print((time.time()-start_time),f)
I don't know if I got you right but I can propose some changes in your code. First - if you want to count number of odd numbers and return True if number of odds is <= 3. you can do it like that:
>>> def count_odds(lst: list):
... count = 0
... for num in lst:
... count += 1 if num % 2 else 0
... return count <= 3
...
>>> count_odds([1, 3, 5, 6])
True
>>> count_odds([1, 3, 7, 9, 11])
False
This function will return True only if there are 3, 2, 1 or 0 odd numbers in list that you've passed to this method.
On the other hand you can achieve your goal by using break in the for loop. Here is the solution:
>>> lst = [1, 3, 5, 7]
>>> count = 0
>>> for num in lst:
... if count > 3:
... break
... count += 1 if num % 2 else 0
>>> print("More than 3") if count > 3 else print("Less than 3")
Less than 3
# Rest of your code.
And another way to do it:
>>> def count_odds(lst: list):
... result = list(map(lambda x: x % 2, lst))
... return sum(result) <= 3
...
>>> count_odds([1, 3, 7])
True
>>> count_odds([1, 3, 7, 9])
False
The map function takes every element of the lst list, then returns True if element is odd, False otherwise. Then the sum function sums all the True values of the result list and gives you the answer.
I have to implement a recursive function which recieves only two arguments: 'n' and 'k', where n is the length of a set of from '0' to 'n-1' and k is the length of the subsets of different elements from the original set. We have to return finally a list of lists which contains these all sub-lists in k-length. The twist here that I don't know to overcome is we mustn't use other arguments such as lists, tuples, sets, etc...
So I don't know how to "save" in recursion the list of all subsets without "lost" details.
def ret_k_subset(n, k):
if n >= 0 and k >= 0:
lst = []
if len(lst) == k:
return lst
else:
for n in range(n):
return lst + ret_k_subset(n, k)
return lst
I thought of something like that but it always returns an empty list...
So I think I need to understand how do I save data structures consistently in recursion.
Thanks.
It can be done in few ways, IMO the simplest is to take that recursion step that uses property that last element (n-1) is or isn't in result list and with appropriate recursion result construct it's result. Here is implementation:
def ret_k_subset(n, k):
if k == 0:
return [[]]
if k == n:
return [list(range(n))]
return ret_k_subset(n - 1, k) + [x + [n - 1] for x in ret_k_subset(n - 1, k - 1)]
Basically I'm trying to find 2 elements in a list that adds together to the correct given sum.
Example:
aList = [1,5,6,3,8,9,4] sum = 10
now with the above conditions I will expect 2 results:
[1, 9] and [6, 4]
The answer should be [6, 4] because they are closest to each other. 1 to 9 need to take 4 steps while [6, 4] only need to take 3. Shortest index differences.
My code is below and it doesn't work for the above example:
def sum_pairs(ints, s):
for i in ints:
for b in ints[i:]:
if i + b == s:
return [i,b]
else:
return None
So how would you check between closest index with out writing another loop?
if you want to find numbers with least ammount of steps, loop over the distance and try all tuples with the given distance in between - you should not try pairs with 4 spaces in between when you did not exhaust all tuples with distance 3...
def sum_pairs(ints, s):
for distance in range(1, len(ints)):
for idx in range(len(ints) - distance):
if ints[idx] + ints[idx + distance] == s:
return [ints[idx], ints[idx + distance]]
return None
You weren't really testing at all for the differences between the pairs that you have, simply returning the list of all matches found for the sum you entered.
nums = [1,5,6,3,8,9,4]
def sum_pairs(ints, s):
matches = []
for i in range(len(ints)):
x = ints[i]
for y in ints[i + 1:]:
if x + y == s: matches.append([x, y])
differences = {}
for x, y in matches:
differences[abs(x - y)] = [x, y]
return differences[min(differences.keys())]
>>> sum_pairs(nums, 10)
# [6, 4]
You need to store all possible solutions to the list before returning anything.
a = []
def sum_pairs(ints, s):
for i in ints:
for b in ints[i:]:
if i + b == s:
a.append([i,b])
return a
aList = [1,5,6,3,8,9,4]
print sum_pairs(aList,10)
Output: [[1, 9], [6, 4]]
A "simple" (not most efficient - see another posted answer : adding up a loop to procede by looking at spaces between characters is better) solution :
def sum_pairs(ints, s):
answer = None
distance = 10
for i in ints:
for b in ints[i:]:
if i + b == s and abs(i - b) < distance:
answer = (i, b)
distance = abs(i - b)
return answer
def alternating(l):
f=0
if len(l)==0 or len(l)==1:
f=1
for i in range(0,len(l)):
if i==len(l)-3:
break
if l[i]<l[i+1]:
if l[i+1]>l[i+2]:
f=1
if l[i]>l[i+1]:
if l[i+1]<l[i+2]:
f=1
if f==1:
return(True)
if f==0:
return(False)
I have tried this logic but not working.
i want to solve this problem.
returns True if the values in the input list alternately go up and down.
You can use itertools.cycle with operator.lt and operator.gt here to handle which delta you wish to check next and pair up each adjacent elements using zip, then use the builtin all function to make sure that all comparisons are True, eg:
from itertools import cycle
from operator import lt, gt
def is_alternating(seq):
# First element must be less, next must be more, repeat...
# (can be changed to lt, lt, lt, gt or whatever pattern is required)
ops = cycle([lt, gt])
# Zip the ops and the pairs of numbers
it = zip(ops, zip(seq, seq[1:]))
# Check that all operations return True - will short circuit on False
return all(f(a, b) for f, (a, b) in it)
for sequence in [[1, 3, 2], [1], [], [1, 2, 3, 4], [2, 4, 1, 5, 3, 7]]:
print(sequence, '->', is_alternating(sequence))
Gives you:
[1, 3, 2] -> True
[1] -> True
[] -> True
[1, 2, 3, 4] -> False
[2, 4, 1, 5, 3, 7] -> True
I believe this will do what you're after.
This code works both ways up -> down -> up and down -> up -> down
def is_alternating(lst):
# check if list is valid
if len(lst) < 3:
return False
# get stating direction
# first element > second = up -> down
# up is True, down is False
direction = lst[0] > lst[1]
for i in range(len(lst) - 1):
if direction:
if not lst[i] > lst[i + 1]:
return False
else:
if not lst[i] < lst[i + 1]:
return False
# invert direction
direction = not direction
return True
# Output
>>> is_alternating( [1, 2, 3, 4] )
False
>>> is_alternating( [1, 2, 0, 4] )
True
>>> is_alternating( [5, 2, 8, 4] )
True
We define alternating as each pair of elements ((s[0],s[1]), (s[1],s[2]) ... ) to have the opposite relation (a<b) then the previous/next pairs. Also if any pair are equal to each other then the sequence is not alternating, meaning the exact function would look like this:
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
def alternating(seq):
last = None
for a,b in pairwise(seq):
if a==b or (a<b) == last:
return False
else:
last = a<b
return True
note that this would return True for sequences with 2 or less elements, if that is not the desired behaviour you would need to add a if len(seq)<3:return False although then this method would not work with iterators like generators.
Start from index i element and compare with previous and next element with it.
I check if element at index i greater than previous and next element or if it is less than previous and next element.
If one of the condition become False then list does not contain alternating elements.
def alternating(l):
if l == [] or len(l) == 1:
return True
for i in range(1,len(l)-1):
if l[i] > l[i-1]:
if not l[i] > l[i+1]:
return False
elif l[i] < l[i-1]:
if not l[i] < l[i+1]:
return False
return True
Did the following steps.-
1. -If the length of list is 0 or 1, return false.
2. if two adjacent element of the list is same then return false.
3. checking the consistency of the list, if it is alternating or not.
4. If not then return false otherwise return true.
def alternating(l): # l is a list !
if len(l) == 0 or len(l) == 1:
return True
for i in range(len(l)-1):
if l[i]==l[i+1]:
return False
for i in range(2,len(l)):
if l[i-2]>l[i-1] :
if (l[i]<l[i-1]):
return False
elif l[i-2]<l[i-1]:
if (l[i] > l[i - 1]):
return False
return True
def alternating(l):
a=b=c=d=0
if len(l)==0 or len(l)==1 or (len(l)==2 and l[0]!=l[1]):
return ("True")
for i in range(0,len(l)-1,2):
if(l[i]<l[i+1]):
a+=1
if(l[i]>l[i+1]):
b+=1
if a!=len(l)//2 and b!= len(l)//2:
return("False")
for i in range(1,len(l)-1,2):
if(l[i]<l[i+1]):
c+=1
if(l[i]>l[i+1]):
d+=1
if c!=(len(l)-1)//2 and d!= (len(l)-1)//2:
return("False")
if a==d or b==c:
return("True")
return("False")
list1 = list()
n = int(input("How many numbers you want to enter in list:"))
for i in range(n):
ele = int(input())
list1.append(ele)
print(list1)
if(list1[0]==9 or list1[1]== 9 or list1[2]==9 or list1[3]==9):
print("True")
else:
print("False")
def alternating(x):
if len(x)==0:
return(True)
for i in range(0,len(x)-2):
if x[i]==x[i+2]:
return(True)
else:
return(False)