Finding minimum element in a list (recursively) - Python - python

I'm trying to find the minimum value in a list of integers using recursion. The main idea is that if the list is only one element long, this element is my minimum.
Else, I divide the list onto two smaller lists of the same size, look for minimum value in both of them and then compare which one is smaller.
The code looks like this:
def minimum(a,l,p):
if l == p:
return a[l]
else:
m1 = minimum(a,l, (l+p)/2)
m2 = minimum(a, (l+p)/2 + 1, p)
if m1 < m2:
return m1
else:
return m2
It doesn't seem to be difficult, however when I tried to run this function for a sample list, I got the following error: "RecursionError: maximum recursion depth exceeded in comparison".
Is something wrong with the algorithm or maybe I should look somewhere else for the reason fo this problem?

Your recursive strategy mentioned is similar a binary search, and it is most effected when traversing a tree to find a generic value as the tree is assumed to be structured in a sorted manner for maximum transversal efficiency. If you are truly intent on solving the problem with recursion, however, you can iterate over the list itself:
def minimum(l, val):
if not l[1:]:
return val
return minimum(l[1:], l[0] if l[0] < val else val)
l = [34, 23, 2, 4, 18]
print(minimum(l, l[0]))
Output:
2

In the end, I believe this is just an example on how to iterate through a list using recursion rather than using a loop and used for learning purposes. You can continuously split the list into halves until you get a list of length 1, which is when you surface the element. If you're doing this for learning purposes, I suggest you add print() statements to see what your list is doing.
def minimum(lst):
if len(lst) == 1:
return lst[0]
else:
m1 = minimum(lst[0:len(lst) / 2])
m2 = minimum(lst[len(lst) / 2:])
if m1 < m2:
return m1
else:
return m2
if __name__ == "__main__":
print(minimum([3, 4, 1, 2, 5]))
print(minimum([3, 2, 1, 0]))
But as #HFBrowning mentioned in a comment, in real life you should just use min(lst) and be done with it.
And as #PatrickHaugh mentioned in a comment to this answer, the division must return an integer. Which means, if you're running this on Python 3, you should change the len(lst) / 2 to len(lst) // 2 (see the double /?)

def RecursiveMin(L):
if len(L)==2:
if L[0]<L[1]:
return L[0]
else:
return L[1]
else:
X= RecursiveMin(L[1:])
if L[0]<X:
return L[0]
else:
return X
This formula will give you the smallest value in list.
L=[99,45,78,34,67,2,34,88]
RecursiveMin(L)
>>> 2

Related

Finding the minimum difference between two elements with recursion

I'm trying to make a "shortest distance algorithm for 1D".
However, I'm confused on the recursive case. I don't know how to get the value back after the recursive calls (lines 14 and 15). How can I fix the following code?
def recCPairDist(points):
if len(points) == 1:
return 0
elif len(points)== 2:
abs(points[1]-points[0])
#how do i assign the result final value back to "leftDist rightDist"
#since its a recurisive, the result can be more than 1, should i store all the result in a list first?
#then get the min(list)?
else:
mid = len(points) // 2
first_half = points[:mid]
second_half = points[mid:]
leftDist = recCPairDist(first_half)
rightDist = recCPairDist(second_half)
midDist = abs(second_half[0] - first_half[1]) #i dont think this is correct since i didnt consider the recursion
return min(leftDist,rightDist,midDist)
def cPairDist(points):
points.sort()
return recCPairDist(points)
P1 = [7, 4, 12, 14, 2, 10, 16, 6]
cPairDist(P1)
The expected result for P1 should be 1, since the shortest distance would be between 7 and 6.
You're really close! There's three things you have to do:
For the case where there's only one point to consider, you should not return 0. For example, for the array [3, 6, 9], the answer is 3, but your given base case will return 0. This is because one of the resulting subarrays will be of length 1 for odd-length arrays, and the zero return value will propagate when you return from each recursive call.
You need to return the value abs(points[1]-points[0]) in the len == 2 base case explicitly using the return keyword.
For your recursive case, the minimum difference must be between two consecutive elements in the left half, two consecutive elements in the right half, or between the last element of the first half and the first element of the second half (two consecutive elements in the original array, but not covered in the two recursive cases). So, your midDist should compute this value.
Here is a code snippet that resolves all three of these issues:
def recCPairDist(points):
if len(points) == 1:
return float('inf')
elif len(points)== 2:
return abs(points[1]-points[0])
else:
mid = len(points) // 2
first_half = points[:mid]
second_half = points[mid:]
leftDist = recCPairDist(first_half)
rightDist = recCPairDist(second_half)
midDist = abs(first_half[-1] - second_half[0])
return min(leftDist,rightDist,midDist)

Ceiling of the element in sorted array

Hi I am doing DSA problems and found a problem called as ceiling of the element in sorted array. In this problem there is a sorted array and if the target element is present in the sorted array return the target. If the target element is not found in the sorted array we need to return the smallest element which is greater than target. I have written the code and also done some test cases but need to check if everything works correctly. This problem is not there on leetcode where I could run it with many different cases. Need suggestion/feedback if the problem is solved in the correct way and if it would give correct results in all cases
class Solution:
#My approch
def smallestNumberGreaterThanTarget(self, nums, target):
start = 0
end = len(nums)-1
if target > nums[end]:
return -1
while start <= end:
mid = start + (end-start)//2
if nums[mid] == target:
return nums[mid]
elif nums[mid] < target:
if nums[mid+1] >= target:
return nums[mid+1]
start = mid + 1
else:
end = mid-1
return nums[start]
IMO, the problem can be solved in a simpler way, with only one test inside the main loop. The figure below shows a partition of the real line, in subsets associated to the values in the array.
First, we notice that for all values above the largest, there is no corresponding element, and we will handle this case separately.
Now we have exactly N subsets left, and we can find the right one by a dichotomic search among these subsets.
if target > nums[len(nums)-1]:
return None
s, e= 0, len(nums);
while e > s:
m= e + ((s - e) >> 1);
if target > nums[m]:
s= m+1
else:
e= m
return s
We can formally prove the algorithm using the invariant nums[s-1] < target <= nums[e], with the fictional convention nums[-1] = -∞. In the end, we have the bracketing nums[s-1] < target <= nums[s].
The code errors out with an index out-of-range error for the empty list (though this may not be necessary because you haven't specified the problem constraints).
A simple if guard at the top of the function can fix this:
if not nums:
return -1
Otherwise, it seems fine to me. But if you're still not sure whether or not your algorithm works, you can always do random testing (e.g. create a linear search version of the algorithm and then randomly generate inputs to both algorithms, and then see if there's any difference).
Here's a one-liner that you can test against:
input_list = [0, 1, 2, 3, 4]
target = 0
print(next((num for num in input_list if num >= target), -1))

Code simplifcation using iteration and recursion

I would like to 1)simplify the code below using iteration 2)implement it using recursion
This code features an equation similar to the Fibonacci series the difference being the previous answer is multiplied by a function in this case just 2 by index.
The algorithm will input different images and calculate the total incremented points, the flattened optimal matrix will give the highest value.
Note that list_c should give the highest value.
sum_list=[]
list_a= [1,0,1,0,1]
list_b= [1,0,0,1,1]
list_c= [1,1,1,0,0]
def increment(input_list):
global i #i added it because i received an error
""" returns
Incrementing_answer = previous_answer + (list[i+1])
for which previous_answer begins with list[0]
if list[0] =0 then list[0]=-1
for example, list_a should be evaluated as follows
- ans = 1+2*(1)
= 3
- ans = 3+ 2*(0) --since since its 0 ,-1 is replaced
= 3+ 2*(-1)
= 1
- ans = 1+2(1)
=3
and so on
Incrementing_answers = sum_list=[3,1,3,1,3] =11
"""
for i in range(0,len(input_list)):
if input_list[i] == 0 :
input_list[i] == -1
ans = input_list[i]+2*input_list[i]
sum_list.append(ans)
else:
ans = ans+input_list[i]
sum_list.append(ans)
return sum(sum_list)
Previous answers have been helpful, the code above does not work
1)I would like corrections
2)Is it possible to solve the same problem using recursion
3) I also just realised the code does not work well for large arrays(preprocesed_images)
4) for lists or arrays that include floating points I get the error ('
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()')
3)Feedback on using good programming practices
4) Any additional advice on how to tackle the problem is Welcome, the inputted images will be captured using cv2 and the algorithm has to pick optimal images in real-time, to solve the puzzle.
Thanks very much in advance
Global variables are discouraged over passing arguments as parameters to function
Use of PEP 8 naming conventions is encouraged (i.e. name function increment rather than Increment)
Single letter variable names are discouraged (i.e. no idea of what a, l, p represents) (adopting Dan's comment below).
Code
def increment(a, l, p):
"""
Returns in an incrementing value ,using the formula a(n)=a(n)+l(i+1)
were a(n) starts with the starts with l[0] and then l(i+1)
"""
for i in range(len(l)):
if l[i] == 0: # equation
a += -2 # no change to l
else:
a += 2*l[i]
p.append(a)
return sum(p)
Usage
l = [1,0,1,0,1]
p=[]
a = 0
print(f'Increment: {increment(a, l, p)}')
print(f'l unchanged: {l}')
print(f'Updated p: {p}')
a = p[-1] # a is last p
print(f'Updated a: {a}')
Output
Increment: 6
l unchanged: [1, 0, 1, 0, 1]
Updated p: [2, 0, 2, 0, 2]
Updated a: 2
a doesn't need to be a global and p & l should be passed as argumets -in your version you tied your implementation of your function to the implementation of the calling code - a better implementation would be :
I don't fully understand why you need a at all, but I think this code does what you need :
def Increment( initial, results ):
"""
Returns in an incrementing value ,using the formula a(n)=a(n)+l(i+1)
were a(n) starts with the starts with l[0] and then l(i+1)
,if l[i]= 0,-1 is calculated instead.
"""
last = results[-1] if results else 0
for index, value in enumerate(initial):
term = -1 if value == 0 else value
last += 2* term
results.append(last)
return sum(results)
l = [1,0,1,0,1]
p=[]
r = Increment(initial=l, results=p)
print(r)
If you do need the a value outside the function it will just be p[-1]
I think the above code replicates the functionality, without changing your l list (which you indicated you didn't need.

How to use recursion to implement "Finding the maximum value in an array" in Python?

How to use recursion to implement "Finding the maximum value in an array" in Python ?
The following is a simple test code I wrote
I want to do it by recursion
I'm learning algorithms, learning recursion.
Thanks very much!
def max(list):
if list == []:
msg = "List: ..."
return msg
max = list[0]
for item in list[1:]:
if item > max:
max = item
return max
data = [8,2,-690,4,12,-320,0, 98]
print(max(data))
If you want to use recursion, it's very important to define carefully the end cases.
The maximum of the elements of a list is, obviously, either the first element or the maximum of the rest of the list: it's the greatest of the two values. That's actually the recursion you are looking for.
But what happens when there is no first element? You have an empty list, and an undefined behaviour. Why not maximum([]) = 0? Because it would lead to some inconsistency: maximum([-1]) = greatest(-1, maximum([])) = greatest(-1, 0) = 0. (You could also try maximum([]) == -math.inf, but this won't be very intuitive!)
What if the rest of the list is empty? No problem, you have just one element and it is the maximum.
Just translate this analysis into code:
def maximum(xs):
if len(xs) == 0:
raise ValueError()
elif len(xs) == 1:
return xs[0]
else:
u = xs[0]
v = maximum(xs[1:])
return u if u >= v else v # greatest(u, v)
More on maximum([])
I will try to give a value to maximum([]). I repeat the argument above. For any given n, maximum([n]) = greatest(n, maximum([])) = n. This implies that, for every n, maximum([]) <= n. The only value that meets this condition is -math.inf. Why not define maximum([]) == -math.inf? Imagine you create a minimum function. For symetrical reasons, you will have to define minimum([]) == math.inf. Hence it exists a list l0 = [] such that minimum(l0) > maximum(l0). No one would accept such a possibility.
What should we do now? There are two main possibilities: defensive programming or use a contract. In defensive programming, the function will check the arguments it has received, and fail if one of these arguments is not correct. That's what I did:
def maximum(xs):
if len(xs) == 0:
raise ValueError()
...
If you use a contract, you will basically say: if you give this function an empty list, then the behaviour is undefined. It might return any value, crash, loop forever, .... Here, you would have something like:
def maximum(xs):
"""!!! xs must not be empty !!!"""
...
It seems the same, but there is a huge difference. You can use, for implementation reasons, -math.inf as the return value for maximum([]), because it is now clear that it doesn't have any meaning. Someone who tries to check if minimum(l0) <= maximum(l0) for l0 = [] clearly breaks the contract and won't be surprised by the result. Of course, if you want to make it robust, you will write:
def maximum(xs):
"""PRECONDITION: xs must not be empty"""
assert len(xs) != 0 # can be disabled at runtime at your own risks
_maximum(xs)
def _maximum(xs):
"""no precondition here"""
if len(xs) == 0:
return -math.inf
else:
u = xs[0]
v = _maximum(xs[1:])
return u if u >= v else v # greatest(u, v)
Try this (using recursion, as requested by the OP):
def largest(arr):
if len(arr) == 2:
return arr[1] if arr[1] > arr[0] else arr[0]
else:
return largest([arr[0], largest(arr[1:])])
No built-in functions are used (such as max) because the OP has stated that they don't wish to use any built-in functions.
The else part of the function returns either the first element of the list or the largest number in the list (excluding the first element) depending on whichever number is larger.
Each time the else part is executed, the largest(arr[1:]) bit checks which number is largest inside arr without the first element. This means that, at one point, arr will contain two elements. When it does so, a one-line if statement is used to compare the two elements and returns the larger element.
Eventually, the code recurses back to the first level and returns the largest element.
I would write max and max_all
from math import inf
def max (a, b):
if a > b:
return a
else:
return b
def max_all (x = -inf, *xs):
if not xs:
return x
else:
return max (x, max_all (*xs))
max_all can be called with any number of arguments
print (max_all (8, 2, -690, 4, 12, -320, 0, 98))
# 98
Or use * to unpack arguments
data = [ 8, 2, -690, 4, 12, -320, 0, 98 ]
print (max_all (*data))
# 98
It even works when 0 inputs are given
print (max_all ())
# -inf
def Maximum(list):
if len(list) == 1:
return list[0]
else:
m = Maximum(list[1:])
if m > list[0] else list[0]:
return m
def main():
list = eval(raw_input(" please enter a list of numbers: "))
print("the largest number is: ", Maximum(list))
main()
The simplest way
max and list are built-in functions. So you want to avoid using those identifiers yourself.
Here's a simple version that uses recursion:
#/usr/bin/python
def largest(arr):
if not arr:
return None
else:
r = largest(arr[1:])
if r > arr[0]:
return r
else:
return arr[0]
data = [8, 2, -690, 4, 12, -320, 0, 98]
print(largest(data))

Add minimum and maximum number in list using Recursion: Python

I wrote a recursive function to find the summation of a list, here is my code:
def rsum (eleList):
if len(eleList) == 1:
return eleList[0]
else:
return eleList[0] + rsum(eleList[1:])
However, right now I want to write a recursive function to find the summation of the max and min of a list, and I have no clue where I should start. Could anyone give me some hint?
If you want to write a recursive function, you have to figure out how to solve this problem based on having solved a smaller problem. You know that the sum of this list is the first element plus the sum of the rest of the list. If you have a list:
[1,2,3,4,5]
and you know that the max of the last four elements is 5 and the first element is 1, and you want to find the total maximum, how do you do that in a constant number of operations?
I would search for maximum and minimum value in each iteration. And if that is the case, I will return the sum.
Something like:
def rsum(eleList, ans, index):
if index == len(eleList) - 1:
if max(eleList) == eleList[index] or min(eleList) == eleList[index]:
return ans+eleList[index]
else:
return ans
else:
if max(eleList) == eleList[index] or min(eleList) == eleList[index]:
return ans + eleList[index] + rsum(eleList, ans, index + 1)
else:
return rsum(eleList, ans, index + 1)
print rsum([9, 2, 3, 4], 0, 0)
Output:
11
Might not be the smartest one or most pythonic but it gets things done.
For finding the sum of all the elements of the list use sum function:
temp = [1,2,3,4]
sum(temp)
#output = 10
If you want to find sum of min and max elements, get the list sorted and add first and last element:
temp = [1,2,3,4]
sorted_list = sorted(temp)
total = sorted_list[0] + sorted_list[-1]
Avoid making your own functions whenever there is a possibility of built-in function being present.

Categories

Resources