Median of sorted arrays of equal length - python-3.x

I am trying to find the median of two sorted array of same length for this I am using divide and conquer algorithm. But my code returns None instead of a value
Here is code to find median of single array:
def getmedian(li):
x = len(li)
if x%2 == 0:
return (li[x//2] + li[(x//2)-1])/2
else:
return li[(len(li)-1)//2]
and then I'm using following function for two arrays:
def TwoList(list1,list2):
if len(list1) == 1:
return (list1[0] + list2[0])/2
elif len(list2)== 2:
return (max(list1[0],list2[0]) + min(list2[1], list1[1]))/2
else:
#pdb.set_trace()
x = getmedian(list1)
y = getmedian(list2)
if x == y:
return x
elif x > y:
if len(list1)%2==0:
TwoList(list1[:len(list1)//2], list2[len(list1)//2:])
else:
TwoList(list1[:len(list1)//2+1], list2[len(list1)//2:])
else:
if len(list1)%2==0:
TwoList(list1[len(list1)//2:], list2[:len(list1)//2])
else:
TwoList(list1[len(list1)//2:], list2[:len(list1)//2+1])

Looks like you are doing it right except returning value in TwoList recursive calls.
Please see below code, commented where you have to return value.
def getmedian(li):
x = len(li)
if x%2 == 0:
return (li[x//2] + li[(x//2)-1])/2
else:
return li[(len(li)-1)//2]
def TwoList(list1,list2):
if len(list1) == 1:
return (list1[0] + list2[0])/2
elif len(list2)== 2:
return (max(list1[0],list2[0]) + min(list2[1], list1[1]))/2
else:
#pdb.set_trace()
x = getmedian(list1)
y = getmedian(list2)
if x == y:
return x
elif x > y:
if len(list1)%2==0:
return TwoList(list1[:len(list1)//2], list2[len(list1)//2:]) # return value
else:
return TwoList(list1[:len(list1)//2+1], list2[len(list1)//2:]) # return value
else:
if len(list1)%2==0:
return TwoList(list1[len(list1)//2:], list2[:len(list1)//2]) # return value
else:
return TwoList(list1[len(list1)//2:], list2[:len(list1)//2+1]) # return value
print(TwoList([1,2,3,4],[5,6,7,8]))

Related

PYTHON: projecteuler 60

I have some trouble about project euler problem 60.
The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.
Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.
The code that I created is too slow to see the correct answer. And I don't even see that is it work correctly or not. The code is:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Aug 27 21:18:10 2022
#author: burak
"""
def is_prime(n, check_list_for_primes): #checks if value is prime
if check_list_for_primes.count(n) > 0: #checks if valu calculated before. if it were, it avoid loop.
return True
else:
if n == 1:
return False
if n == 2 or n == 3:
return True
i = 2
while i * i <= n:
if n % i == 0:
return False
exit(0)
i += 1
check_list_for_primes.append(n) # if it never calculated, stores the value to avoid loop at the beginning of function.
return True
def check_1(i, j): # checks the concanated calues if they are primes.
if is_prime(int(str(i)+str(j)), check_list_for_primes) == True and is_prime(int(str(j)+str(i)), check_list_for_primes) == True:
return True
else:
return False
def check_2(temp_list, n): # checks the final list that obtain the minimum summation.
if temp_list.count(n) == 0:
temp_list.append(n)
for i in temp_list:
for j in temp_list:
if len(temp_list) == 1:
return check_1(i, j)
elif i == j:
continue
elif len(temp_list) == 1:
return True
break
elif check_1(i, j) == False:
return False
return True
def func_(prime_list): # creates a dictionary summation of the five prime numbers in order to problem.
temp_list = []
result_dic = {}
k = 0
t = 0
for i in prime_list:
if i == 5:
continue
while k == 0:
t = k
for j in prime_list:
if i == j or j == 5:
continue
elif j < i:
continue
else:
temp_list.append(j)
if check_2(temp_list, i) == True:
continue
else:
temp_list.remove(j)
if t > 0 and len(temp_list) > 1:
t -= 1
temp_list.remove(max(temp_list))
continue
if len(temp_list) == 5:
result_dic[sum(temp_list)] = temp_list
elif len(temp_list) < 5:
k +=1
temp_list = []
return result_dic
if __name__ == "__main__":
dic_ = {}
prime_list = []
check_list_for_primes = []
for i in range(3, 9000, 1): #creates prime list between given range
if is_prime(i, check_list_for_primes) == True:
prime_list.append(i)
check_list_for_primes = prime_list.copy() #pseudo prime list to avoid calculating if the number is prime.
dic_ = func_(prime_list) #final dictionary to obtain minimum summation of five prime numbers.
x = min(list(dic_.keys()))
print(str(x) + " : " + str(dic_[x]))
I tried to type the examination of calculating order.
The main problem is at "func_" function. The for loop of "j" must be manipulated if the code not to get required list lenght. The "j" loop must be restart again after remove second element of "temp_list" and it must be start after shift to removed element of "prime_list".
Could you help me to see where I made mistakes and how can I improve calculation speed. Thanks so much.
I solved it. while loop changed and the "j" for loop determined by a list. The final code is;
def is_prime(n, check_list_for_primes): #checks if value is prime
if check_list_for_primes.count(n) > 0: #checks if valu calculated before. if it were, it avoid loop.
return True
else:
if n == 1:
return False
if n == 2 or n == 3:
return True
i = 2
while i * i <= n:
if n % i == 0:
return False
exit(0)
i += 1
check_list_for_primes.append(n) # if it never calculated, stores the value to avoid loop at the beginning of function.
return True
def check_1(i, j): # checks the concanated values if they are primes.
if is_prime(int(str(i)+str(j)), check_list_for_primes) == True and is_prime(int(str(j)+str(i)), check_list_for_primes) == True:
return True
else:
return False
def check_2(temp_list): # checks the final list that obtain the minimum summation.
for i in temp_list:
for j in temp_list:
if len(temp_list) == 1:
return check_1(i, j)
elif i == j:
continue
elif len(temp_list) == 1:
return True
break
elif check_1(i, j) == False:
return False
return True
def func_(prime_list): # creates a dictionary summation of the five prime numbers in order to problem.
prime_list.remove(5)
temp_list = []
result_dic = {}
# k = 0
copy_primes = prime_list.copy()
for i in prime_list:
for z in prime_list:
if z <= i:
copy_primes.remove(z)
else:
break
if i == max(prime_list):
break
elif i == 5:
continue
# for z in range(len(prime_list) - 1, 0, -1):
# if check_1(i,prime_list[z]) == True:
# max_prime_of_i = prime_list[z]
# break
while len(temp_list) < 5:
# if temp_list[1] == max_prime_of_i:
# break
if len(temp_list) == 1:
break
if len(copy_primes) == 0 and len(temp_list) > 1:
copy_primes = prime_list.copy()
for z in prime_list:
if z <= temp_list[1]:
copy_primes.remove(z)
else:
break
temp_list = []
for j in prime_list:
if len(copy_primes) > 0:
j = copy_primes[0]
copy_primes.remove(j)
else:
break
if temp_list.count(i) == 0:
temp_list.append(i)
continue
temp_list.append(j)
temp_list.sort()
if check_2(temp_list) == True and len(temp_list) > 1:
continue
elif check_2(temp_list) == False and len(temp_list) > 1:
temp_list.remove(j)
print(i)
print(temp_list)
if len(temp_list) < 5 and len(copy_primes) == 0:
continue
elif len(temp_list) == 5:
break
copy_primes = prime_list.copy()
if len(temp_list) == 5:
result_dic[sum(temp_list)] = temp_list
print(str(min(list(result_dic.keys()))) + " : " + str(result_dic[min(list(result_dic.keys()))]))
weight_ = 0
check_weight = 0
for p in temp_list:
weight_ = weight_ + len(str(p))
if weight_ < check_weight or check_weight == 0:
check_weight = weight_
elif check_weight < weight_ and len(temp_list) == 5:
return result_dic
temp_list = []
return result_dic
if __name__ == "__main__":
dic_ = {}
prime_list = []
check_list_for_primes = []
for i in range(3, 9000, 1): #creates prime list between given range
if is_prime(i, check_list_for_primes) == True:
prime_list.append(i)
check_list_for_primes = prime_list.copy() #pseudo prime list to avoid calculating if the number is prime.
dic_ = func_(prime_list) #final dictionary to obtain minimum summation of five prime numbers.
x = min(list(dic_.keys()))
print(str(x) + " : " + str(dic_[x]))

I've tried running the code but it says list index is out of range

from typing import List
# You are given an integer n, denoting the no of people who needs to be seated, and a list of m integer seats, where 0 represents a vacant seat. Find whether all people can be seated, provided that no two people can sit together
When I run this code in geeks for geeks for submission I get a error that List index is out of range.
but seems to work fine when I run it as a script.
class Solution:
def is_possible_to_get_seats(self, n: int, m: int, seats: List[int]) -> bool:
vacant_seats = 0
if len(seats) == 2:
if seats[0] or seats[1] == 1:
print(seats)
return False
else:
print(seats)
return True
else:
for x in range(len(seats)):
if x == 0:
if seats[x] == 0 and seats[x+1] == 0:
seats[x] = 1
vacant_seats += 1
elif x == len(seats)-1:
if seats[x] == 0 and seats[x-1] == 0:
seats[x] = 1
vacant_seats += 1
else:
if seats[x] == 0:
if seats[x+1] == 0 and seats[x-1] == 0:
seats[x] = 1
vacant_seats += 1
if vacant_seats < n:
return False
else:
return True
# {
# Driver Code Starts
class IntArray:
def __init__(self) -> None:
pass
def Input(self, n):
arr = [int(i) for i in input().strip().split()] # array input
return arr
def Print(self, arr):
for i in arr:
print(i, end=" ")
print()
if __name__ == "__main__":
t = int(input())
for _ in range(t):
n = int(input())
m = int(input())
seats = IntArray().Input(m)
obj = Solution()
res = obj.is_possible_to_get_seats(n, m, seats)
result_val = "Yes" if res else "No"
print(result_val)
# } Driver Code Ends

Counting weighted average doesn't work properly sometimes

I've made a program that counts weighted average and required weighted value to average being equal to our preference. If I want the average be equal to 85 from (the first value in the list is the weight of next values) [[4,72,78],[3,56],[6,93]] and x value of 6 weight it does not output the right value.
def choice(x):
c = 0
Choice = True
choices = []
while Choice:
if choices == []:
if x != 0:
fill = "weight of required value"
else:
fill = "weight of next values"
else:
if x != 0:
fill = "value of wanted weighted average"
else:
fill = "value"
try:
c = input("Give {}\n" .format(fill))
except:
continue
if isinstance(c, str):
if c == "":
Choice = False
if choices == []:
choices = False
break
else:
try:
choices.append(float(c))
except:
continue
if x != 0 and len(choices) == x:
break
c = 0
return choices
def av(x):
c = 0
alist = x[:]
alist.pop(0)
for a in alist:
c += a*x[0]
return c
def average(k,args):
c = 0
n = 0
for y in range(len(args)):
for a in range(len(args)):
c += (av(args[a]))/2
for b in range(len(args)):
n += (args[b][0]*(len(args[b])-1))/2
if k == 1:
return ([float("{0:.2f}".format(c/n)),c,n])
else:
j = float("{0:.2f}".format(c/n))
print("Weighted average {} from {}" .format(j,args))
def rmark(q,args):
alist = average(1,args)
a = float("{:.2f}" .format((((q[1]*(alist[2]+q[0]))-alist[1])/q[0])))
print("To get weighted average {}, u have to add the value equal to {} of weight {}" .format(q[1],a,q[0]))
# return a
Continue = True
list_choices = []
while Continue:
x = 0
x = choice(0)
if isinstance(x, list):
list_choices.append(x)
elif x == False:
break
print(list_choices)
rmark(choice(2),list_choices)
average(0,list_choices)
Let me break it down for you.
av function is reducing the size of your lists (x1, x2 and x3) to 1 by popping (alist.pop(0)) one element.
Hence, value of len(x1)-1 is 0, which means value of all multipliers in the denominator of (av(x1) + av(x2) + av(x3))/((x1[0]*(len(x1)-1)) + (x2[0]*(len(x2)-1)) + (x3[0]*(len(x3)-1))) is 0. Thus, the error divide by zero.

Python IF Else and For loop workflow

I am trying to write a function that returns the number of prime numbers that exist up to and including a given number.
Initially this was my code:
def count_primes(num):
prime = [2]
x = 3
if num < 2:
return 0
while x <= num:
for y in prime:
if x%y == 0:
print('not prime')
x+=2
break
else:
prime.append(x)
x += 2
return len(prime)
How ever I realise this code will run forever because of the following line of code:
for y in prime:
if x%y == 0:
print('not prime')
x+=2
break
else:
prime.append(x)
x += 2
Can anyone help to explain to me why will this end up with an infinite loop compared to the following code?
for y in prime:
if x%y == 0:
print('not prime')
x+=2
break
else:
prime.append(x)
x += 2

Invalid Syntax; nth prime number

def primetest(x):
if x < 2:
return False
if x == 2:
return True
if x % 2 == 0:
return False
for i in range(3,(x**0.5)+1):
if x % i == 0:
return False
return True
def nthprime(n):
primes = []
x = 2
while len(primes) < n:
if primetest(x) == True:
primes.append(x)
x = x + 1
return list(-1)
print nthprime(10001)
Whenever I try to run this it says that "print nthprime(10001)" is invalid syntax.
-prime test is to test wether a number is prime and nthprime creates a list of prime numbers a certain lengths and then return the last element of the list.
print is a function in Python 3, not a statement. You should change your last line of code to:
print(nthprime(10001))
In your code:
def nthprime(n):
primes = []
x = 2
while len(primes) < n:
if primetest(x) == True:
primes.append(x)
x = x + 1
return list(-1) // this is the error
I think you meant primes[-1], like this:
def nthprime(n):
primes = []
x = 2
while len(primes) < n:
if primetest(x) == True:
primes.append(x)
x = x + 1
return primes[-1] // this is now correct
You're also going to need to specify a range in integers, not float. So this:
for i in range(3,(x**0.5)+1):
Becomes this:
for i in range(3,int((x**0.5)+1)): // note the "int"

Resources