Incorrect result implementing jump search in Python - python

I am trying to implement jump search in Python. The code looks logically fine to me. I am getting -1 for all the numbers except for the first element of the array. Can someone help please?
def jumpsearch(array,x):
n=len(array)
m=int(sqrt(n))
if array[0]>x:
return -1
for i in (0,n-1,m):
if array[i]==x:
return i
if x<array[i]:
for k in (i-m,i):
if array[k]==x:
return k
return -1
j=[1,2,3,4,5,6,7,8]
print(j)
jumpsearch(j,2)

When you do for k in (i-m,i): you don't iterate in a range, but k only takes 2 values: i-1 and m.
Same for the line for i in (0,n,m):.
You also get uncorrect results because you never check in the last block. Indeed even by doing for i in range(0, n, m): you will stop when i + m >= n, so you have to check in the last part to be sure that the element is not there.
def jumpsearch(array, x):
n=len(array)
m=int(math.sqrt(n))
if array[0] > x:
return -1
for i in range(0, n, m):
if array[i] == x:
return i
elif x < array[i]:
for k in range(i-m, i):
if array[k]==x:
return k
else:
return -1
for j in range(i+1,n):
if array[j] == x:
return j
else:
return -1

Related

What should I do? I have a recursive function that returns the mth item of a n-bonacci sequence. It has for loop. I am banned from using loops

I have the following recursive function to get the mth term of a n-bonacci sequence as shown below this question. My problem is that the use of for and while loops is totally banned from the code, so I need to get rid off
for i in range(1, n+1):
temp += n_bonacci(n,m-i)
and convert the code into something that is not a loop but nevertheless achieves the same effect. Among the things I can use, but this is not an exclusive enumeration, is: (1) use built-in functions like sum() and .join() and (2) use list comprehensions.
The full code is as follows:
def n_bonacci(n,m): #n is the number of n initial terms; m is the mth term.
if (m < n-1):
return 0
elif (m == n-1):
return 1
else:
temp = 0
#[temp += n_bonacci(n,m-i) for i in range(n)] #this is an attempt at using list comprehension
for i in range(1, n+1):
temp += n_bonacci(n,m-i)
return temp
print("n_bonacci:",n_bonacci(2,10))
print("n_bonacci:",n_bonacci(7,20))
Here's a solution that avoids any type of loop, including loops hidden inside comprehensions:
def n_bonacci_loopless(n, m):
def inner(i, c):
if i == m:
return sum(c)
else:
return inner(i+1, c[-(n-1):] + [sum(c)])
if m < n-1:
return 0
elif (m == n-1):
return 1
else:
return inner(n, [0] * (n-1) + [1])
The base cases are the same, but for recursive cases it initialises a list of collected results c with n-1 zeroes, followed by a one, the sum of which would be the correct answer for m == n.
For m > n, the inner function is called again as long as i < m, summing the list and appending the result to the end of the last n-1 elements of the list so far.
If you are allowed to use comprehensions, the answer is trivial:
def n_bonacci(n,m):
if (m < n-1):
return 0
elif (m == n-1):
return 1
else:
return sum(n_bonacci(n, m-i) for i in range(1, n+1))
You can rewrite the code as follows using list comprehensions:
def n_bonacci(n,m): #n is the number of n initial terms; m is the mth term.
if (m < n-1):
return 0
elif (m == n-1):
return 1
else:
return sum(n_bonacci(n, m-i) for i in range(1, n + 1))
print("n_bonacci:",n_bonacci(2,10))
print("n_bonacci:",n_bonacci(7,20))
To go beyond #Grismar 's answer you can write your own version of sum which doesn't use loops.
def n_bonacci_loopless(n, m):
def recsum(l, s=0):
return recsum(l[1:], s + l[0])
def inner(i, c):
if i == m:
return recsum(c)
else:
return inner(i+1, c[-(n-1):] + [recsum(c)])
if m < n-1:
return 0
elif (m == n-1):
return 1
else:
return inner(n, [0] * (n-1) + [1])

Divide and Conquer. Find the majority of element in array

I am working on a python algorithm to find the most frequent element in the list.
def GetFrequency(a, element):
return sum([1 for x in a if x == element])
def GetMajorityElement(a):
n = len(a)
if n == 1:
return a[0]
k = n // 2
elemlsub = GetMajorityElement(a[:k])
elemrsub = GetMajorityElement(a[k:])
if elemlsub == elemrsub:
return elemlsub
lcount = GetFrequency(a, elemlsub)
rcount = GetFrequency(a, elemrsub)
if lcount > k:
return elemlsub
elif rcount > k:
return elemrsub
else:
return None
I tried some test cases. Some of them are passed, but some of them fails.
For example, [1,2,1,3,4] this should return 1, buit I get None.
The implementation follows the pseudocode here:
http://users.eecs.northwestern.edu/~dda902/336/hw4-sol.pdf
The pseudocode finds the majority item and needs to be at least half. I only want to find the majority item.
Can I get some help?
Thanks!
I wrote an iterative version instead of the recursive one you're using in case you wanted something similar.
def GetFrequency(array):
majority = int(len(array)/2)
result_dict = {}
while array:
array_item = array.pop()
if result_dict.get(array_item):
result_dict[array_item] += 1
else:
result_dict[array_item] = 1
if result_dict[array_item] > majority:
return array_item
return max(result_dict, key=result_dict.get)
This will iterate through the array and return the value as soon as one hits more than 50% of the total (being a majority). Otherwise it goes through the entire array and returns the value with the greatest frequency.
def majority_element(a):
return max([(a.count(elem), elem) for elem in set(a)])[1]
EDIT
If there is a tie, the biggest value is returned. E.g: a = [1,1,2,2] returns 2. Might not be what you want but that could be changed.
EDIT 2
The pseudocode you gave divided into arrays 1 to k included, k + 1 to n. Your code does 1 to k - 1, k to end, not sure if it changes much though ? If you want to respect the algorithm you gave, you should do:
elemlsub = GetMajorityElement(a[:k+1]) # this slice is indices 0 to k
elemrsub = GetMajorityElement(a[k+1:]) # this one is k + 1 to n.
Also still according to your provided pseudocode, lcount and rcount should be compared to k + 1, not k:
if lcount > k + 1:
return elemlsub
elif rcount > k + 1:
return elemrsub
else:
return None
EDIT 3
Some people in the comments highligted that provided pseudocode solves not for the most frequent, but for the item which is present more that 50% of occurences. So indeed your output for your example is correct. There is a good chance that your code already works as is.
EDIT 4
If you want to return None when there is a tie, I suggest this:
def majority_element(a):
n = len(a)
if n == 1:
return a[0]
if n == 0:
return None
sorted_counts = sorted([(a.count(elem), elem) for elem in set(a)], key=lambda x: x[0])
if len(sorted_counts) > 1 and sorted_counts[-1][0] == sorted_counts[-2][0]:
return None
return sorted_counts[-1][1]

Python Pure recursion - Divisor - One input

What is the recursive call (or inductive steps) for a function that returns the number of integers from 1 to N, which evenly divide N. The idea is to concieve a pure recursive code in python for this function. No 'for' or 'while' loops, neither modules can be used. The function num_of_divisors(42) returns 8, representing 1, 2, 3, 6, 7, 14, 21, and 42 as divisors of 42.
def num_of_divisors(n):
return sum(1 if n % i==0 else 0 for i in range(((n+1)**0.5)//1)
Good luck explaining it to your teacher!
If you really can't use for loops (?????????) then this is impossible without simulating one.
def stupid_num_of_divisors_assigned_by_shortsighted_teacher(n, loop_num=1):
"""I had to copy this from Stack Overflow because it's such an
inane restriction it's actually harmful to learning the language
"""
if loop_num <= (n+1) ** 0.5:
if n % loop_num == 0:
return 2 + \
stupid_num_of_divisors_assigned_by_shortsighted_teacher(n, loop_num+1)
else:
return stupid_num_of_divisors_assigned_by_shortsighted_teacher(n, loop_num+1)
else:
if n % loop_num == 0:
return 1
Bonus points: explain why you're adding 2 in the first conditional, but only 1 in the second conditional!
Here you go buddy your teacher'll be happy.
def _num_of_divisors(n, k):
if (k == 0):
return 0
return _num_of_divisors(n, k-1) + (n % k == 0)
def num_of_divisors(n):
return _num_of_divisors(n, n)
It's easier than you think to convert such a simple problem from a loop to a recursive function.
Start with a loop implementation:
n = 42
result = []
for i in range(n+1):
if n % i == 0:
result.append(i)
then write a function
def num_of_divisors_helper(i, n, result):
if <condition when a number should be added to result>:
result.append(n)
# Termination condition
if <when should it stop>:
return
# Recursion
num_of_divisors_helper(i+1, n, result)
Then you define a wrapper function num_of_divisors that calls num_of_divisors_helper. You should be able to fill the gaps in the recursive function and write the wrapper function yourself.
It's a simple, inefficient solution, but it matches your terms.
Without using %
def is_divisible(n, i, k):
if k > n:
return False
if n - i*k == 0:
return True
else:
return is_divisible(n, i, k+1)
def num_of_divisors(n, i=1):
if i > n/2:
return 1
if is_divisible(n, i, 1):
return 1 + num_of_divisors(n, i+1)
else:
return num_of_divisors(n, i+1)
num_of_divisors(42) -> 8
def n_divisors(n,t=1):
return (not n%t)+(n_divisors(n,t+1) if t < n else 0)
good luck on the test later ... better hit those books for real, go to class and take notes...
with just one input i guess
t=0
def n_divisors(n):
global t
t += 1
return (not n%t)+(n_divisors(n) if t < n else 0)

Code to check for symmetry fails some test cases

I am running into trouble trying to get this piece of code to run for all cases:
def symmetric(p):
""" returns true if list is symmetric"""
if p==[]:return True
n=len(p)
m=len(p[0])
if m !=n:
return False
i=0
j=0
t=False
while i < n:
while j < n:
if not p[i][j]==p[j][i]:
return False
j=j+1
i=i+1
return True
When I run this, it passes for some cases.
I can't seem to see what I am doing wrong.
I'd expect [['algebra', 'combinatorics', 'graphs'], ['combinatorics', 'topology', 'sets'], ['graphs', 'topology', 'sets']] to return False but it doesn't.
The break statement only ends the inner while loop.
Since you already found an asymmetry, just use return:
i, j = 0
while i < n:
while j < n:
if not p[i][j] == p[j][i]:
return False
j += 1
i += 1
return True
However, you are not comparing each row with each column at the same index here; because you never reset j back to 0, after the first while j < n loop you'll have j == n and you skip all the remaining loops.
Set j = 0 inside the first while:
i = 0
while i < n:
j = 0
while j < n:
if not p[i][j] == p[j][i]:
return False
j += 1
i += 1
return True
Better still, use for loops over range():
for i in range(n):
for j in range(n):
if not p[i][j] == p[j][i]:
return False
return True

return in python error only returns one value

I am having some trouble with the return. I want to add numbers produced from the function to a list already created but when I return, I just get one value, but if I use print it is fine.
Does the return only produce one value?
def aFunction(n):
for j in range(2,n):
for i in range(2,j):
if (j % i ==0):
break
else:
return(j)
break
print(aFunction(10))
Ok so this time i have edited the code slightly, how can i use p to divide n(which is an int)so that if no remainder remains i can append it to p?
def function(n):
p = [2,]
for j in range(3,n):
if (j // p) == 0:
p.append(j)
return(p)
print(function(20))
Because return terminate the function, so when condition goes to else clause, it terminate the functions,
Use generators:-
def aFunction(n):
for j in range(2,n):
for i in range(2,j):
if j % i == 0:
break
else:
yield j
break
print list(aFunction(10))
Because return terminates the function and returns the value.
You should add these values to a list and then print the list:
def aFunction(n):
l = []
for j in range(2,n):
i in range(2,j):
if (j % i != 0):
l.append(j)
return l
print(aFunction(10))
In Python, you can write a better code:
[j for j in range(2,n) for i in range(2,j) if j % i != 0]

Categories