I develop merge sort, which can use only iterator (it is a statement of the problem). Output of my function is generator.
I write merge sort function:
def merge_sort(data):
data1, data2 = itertools.tee(data)
counter = 0
for i in data1:
counter += 1
if counter < 2:
return data2
middle = int(counter / 2)
y = itertools.islice(data2, 0, middle)
z = itertools.islice(data2, middle, counter)
sorted_y = merge_sort(y)
sorted_z = merge_sort(z)
return heapq.merge(sorted_y, sorted_z)
I test my function:
def main():
unsorted_list = [10, 3, 5, 0, 1, -5, 6, 2]
result = merge_sort(iter(unsorted_list))
for i in result:
print(i)
But It does not work. I only get the number 10. Where I did the mistake?
This is a right function:
def merge_sort(data):
data1, data2, data3 = itertools.tee(data, 3)
counter = 0
for i in data1:
counter += 1
if counter < 2:
return data3
middle = int(counter / 2)
y = itertools.islice(data2, 0, middle)
z = itertools.islice(data3, middle, counter)
sorted_y = merge_sort(y)
sorted_z = merge_sort(z)
return merge(sorted_y, sorted_z)
Related
Two random integer arrays/lists have been given as ARR1 and ARR2 of size N and M respectively. Both the arrays/lists contain numbers from 0 to 9(i.e. single digit integer is present at every index). The idea here is to represent each array/list as an integer in itself of digits N and M.
You need to find the sum of both the input arrays/list treating them as two integers and put the result in another array/list i.e. output array/list will also contain only single digit at every index.
NOTE:
The sizes N and M can be different.
Output array/list(of all 0s) has been provided as a function argument. Its size will always be one more than the size of the bigger array/list. Place 0 at the 0th index if there is no carry.
No need to print the elements of the output array/list.
def sumOfTwoArrays(arr1, n, arr2, m, output) :
#Your code goes here
#Taking Input Using Fast I/O
def takeInput() :
n = int(stdin.readline().rstrip())
if n == 0 :
return list(), 0
arr = list(map(int, stdin.readline().rstrip().split(" ")))
return arr, n
#to print the array/list
def printList(arr, n) :
for i in range(n) :
print(arr[i], end = " ")
print()
#main
t = int(stdin.readline().rstrip())
while t > 0 :
arr1, n = takeInput()
arr2, m = takeInput()
outputSize = (1 + max(n, m))
output = outputSize * [0]
sumOfTwoArrays(arr1, n, arr2, m, output)
printList(output, outputSize)
t -= 1
Sample Input:
1
3
6 2 4
3
7 5 6
Sample Output:
1 3 8 0
This problem can be solved by a simple function like this:
(Note - you can made adjustment on the last line of return result if needed to meet the "strange requirement" of - 'place 0 at the 0th index if there is no carry'. It's left as a trivial exercise. )
def sum_two_array(L1, L2):
carry, total = 0, 0
m, n = len(L1), len(L2)
k = max(m, n)
result = [0] + [0] * k # add +1
for i in range(1, k+1):
a = L1[m-i] if m - i >= 0 else 0
b = L2[n-i] if n - i >= 0 else 0
total = a + b + carry
result[k-i + 1] = total % 10
carry = total // 10
if carry > 0: result[0] = carry
return result if result[0] != 0 else result[1:]
if __name__ == '__main__':
L1 = [6, 4, 4]
L2 = [7, 5, 6]
print(sum_two_array(L1, L2)) # [1, 4, 0, 0]
print(sum_two_array([6, 2, 4], [7, 5, 6])) # [1, 3, 8, 0]
print(sum_two_array([1, 2, 4], [8, 0])) # [2, 0, 4]
JAVA CODE:
import java.lang.Math;
public class Solution {
public static void sumOfTwoArrays(int arr1[], int arr2[], int output[]) {
int n = arr1.length; //size of arr1
int m = arr2.length; //size of arr2
int o = n+1; //size of output array
int sum1 = 0, sum2=0, totalSum=0;
//storing sum of arr1 in sum1
for(int i=0; i<n; i++)
{
sum1+= arr1[i] * Math.pow(10,(n-1-i));
}
//storing sum of arr2 in sum2
for(int i=0; i<m; i++)
{
sum2+= arr2[i] * Math.pow(10, (m-1-i));
}
totalSum = sum1+sum2;
//storing totalSum in reverse order in output array
for(int i=o-1; i>=0; i--)
{
output[i] = totalSum % 10;
totalSum = totalSum/10;
}
}
}
Explanation:
condition: arr1[n], arr2[m], output[n+1]
Instead of calculating sum of unit, tens, and so on digits of both the arrays.
we first calculate the sum1 of arr1, and sum2 of arr2, by using:
number at index * (10 ^ ((n-1) - index)) concept.
sum1 and sum2 are equal to the n and m sized numbers of respective arrays
we store totalSum = sum1+sum2
we store totalSum's every digit in output[n+1] array
we store it in reverse order by using % and / operations
i am using python version 3.7.Below is the code in which I am performing operation along the rows. i want the mean of the data which are along the rows but I get an error. i am new to numpy and python. i am reading the data from text file.
My code is:
import numpy as np
def getIndexFromDatetime(date_from, date_to):
'''date_from = [2, 10] : 10oclock of day2
'''
if date_from[1] > 24 or date_to[1] > 24: print('error')
start = (date_from[0] - 1) * 48 + date_from[1] * 2
end = (date_to[0] - 1) * 48 + date_to[1] * 2
return [start, end]
def is_num(s):
return s.replace(',', '').replace('.', '').replace('-', '').isnumeric()
def get_dataset(fpath):
with open(fpath, 'r') as f:
cnt = 0
DataWeather = {}
header = []
dtime = []
temp1 = []
temp2 = []
for line in f:
terms = line.split('\t')
#print(terms)
if cnt == 0: header1 = terms
if cnt == 1: header2 = terms
#header.append(terms[3])
cnt += 1
if cnt == 2:
for i in range(len(header1)):
header.append(header1[i]+header2[i])
#print(header)
for i in range(len(terms)):
DataWeather[header[i]] = []
#break
if cnt > 2:
for i in range(len(terms)):
if is_num(terms[i]):
DataWeather[header[i]].append(float(terms[i]))
else:
DataWeather[header[i]].append(terms[i])
for i in range(len(DataWeather[header[0]])):
dtime.append(DataWeather[header[0]][i]+' '+DataWeather[header[1]][i])
return DataWeather, header
def get_data(dataset, header, idx):
y = dataset[header][idx[0]:idx[1]]
return y
data_dir = 'weather_data'
month = 3
day = list(range(1,10))
header_idx = [2,3,4,5,7,16]
for d in day:
print(d)
dtime_from = [d, 9]
dtime_to = [d, 18]
dtime_idx = getIndexFromDatetime(dtime_from, dtime_to)
fpath = '{0}/2019-{1:02}.txt'.format(data_dir, month)
dataset, header = get_dataset(fpath)
for h in header_idx:
print(fpath)
print(header[h], dtime_from, dtime_to, dtime_idx)
data = get_data(dataset, header[h], dtime_idx)
#data= list(map(float,np.array(data)))
#data = map(np.array(data, dtype=np.float))
print(data)
print(np.mean(data))
i am getting the following error:
ret = umr_sum(arr, axis, dtype, out, keepdims)
TypeError: cannot perform reduce with flexible type
i also tried some functions like "map" and "list" as commented in the code still it gives error of converting string to float.
I am trying to define a function, median, that consumes a list of numbers and returns the median number from the list. If the list is empty, then I want to return None. To calculate the median, I need to find the middle index of the list after it has been sorted. Do not use a built-in function.
SURVEY_RESULTS = [1.5, 1, 2, 1.5, 2, 3, 1, 1, 1, 2]
def median(SURVEY_RESULTS):
length = 0
order = sorted(SURVEY_RESULTS)
I'm not sure how to use indexing to now determine the median.
Here is my implementation:
def QuickSort(myList,start,end):
if start < end:
i,j = start,end
base = myList[i]
while i < j:
while (i < j) and (myList[j] >= base):
j = j - 1
myList[i] = myList[j]
while (i < j) and (myList[i] <= base):
i = i + 1
myList[j] = myList[i]
myList[i] = base
QuickSort(myList, start, i - 1)
QuickSort(myList, j + 1, end)
return myList
def median(l):
half = len(l) // 2
return (l[half] + l[~half])/2 # Use reverse index
SURVEY_RESULTS = [1.5, 1, 2, 1.5, 2, 3, 1, 1, 1, 2]
# Sort first
QuickSort(SURVEY_RESULTS, 0, len(SURVEY_RESULTS)-1)
result = median(SURVEY_RESULTS)
print (result)
My apologies, I'm new to StackOverFlow & Python. I've written a code for Merge_Sort but it's not running as the values of arrays are getting lost while returning from recursion calls.
Coding Environment: Python3.x
OS: Linux ( Ubuntu 18.04)
Below is my code:
class sort:
def __init__(self, arr, n):
self.arr = arr
self.n = n
def __init__(self, arr, m, n):
self.arr = arr
self.m = m
self.n = n
arrS = arr.copy()
arrL = [0] * (n - int((m + n)/2) + 1)
arrR = [0] * (n - (m + 1))
def Merge_sort(self,arr,first,last):
mid = int((first + last) / 2)
arrMain = arr[first:last+1]
arrLeft = arr[first:mid+1]
arrRight = arr[mid+1:last+1]
arrL = [0] * (mid - first + 1)
arrR = [0] * (last - mid + 1)
arrN = [0] * ( last - first + 1)
if first < last:
#Sort Left Array
self.Merge_sort(arr, first, mid)
#Sort Right Array
self.Merge_sort(arr, mid+1, last)
#I defined the below 3 variables while debugging to view the list
arrL = arr[first:mid+1]
arrR = arr[mid+1:last+1]
print("Left Array: " + str(arrL))
print("Right Array: " + str(arrR))
x = len(arrL)
y = len(arrR)
i = j = k = 0
while i < x and j < y:
if (arrL[i] <= arrR[j]):
arrN[k] = arrL[i]
i += 1
else:
arrN[k] = arrR[j]
j += 1
# end-if#001
k += 1
while (i < x):
arrN[k] = arrL[i]
i += 1
k += 1
while (j < y):
arrN[k] = arrR[j]
j += 1
k += 1
arr = arrN.copy()
print("Merged Array:" + str(arr))
return arrN
#End-if#001
from Sort import sort
arr = [7, 5, 4 ,9, 3, 2 , 0, 1, 6, 8]
n = 0
sort4 = sort(arr, 0, int(len(arr)))
sort4.arr = arr.copy()
sort4.Merge_sort(sort4.arr, 0, int(len(arr)) - 1)
Input of the program: arr = [7, 5, 4 ,9, 3, 2 , 0, 1, 6, 8]
Output of the program: Left Array: [7, 5, 4, 9, 3] Right Array: [2, 0, 1, 6, 8]
Merged Array:[2, 0, 1, 6, 7, 5, 4, 8, 9, 3]
At the end of program it just seems to merge my original array.
Kindly suggest.
Just to notify you, the problem is resolved. I wasn't returning the values correctly. Below is my code just for the reference.
def Merge_sort(self,arr,first,last):
mid = int((first + last) / 2)
arrMain = arr[first:last+1]
arrLeft = arr[first:mid+1]
arrRight = arr[mid+1:last+1]
arrL = [0] * (mid - first + 1)
arrR = [0] * (last - mid + 1)
arrN = [0] * ( last - first + 1)
if first < last:
#Sort Left Array
arrL = self.Merge_sort(arr, first, mid)
#Sort Right Array
arrR = self.Merge_sort(arr, mid+1, last)
#arrL = arr[first:mid+1]
#arrR = arr[mid+1:last+1]
print("Left Array: " + str(arrL))
print("Right Array: " + str(arrR))
x = int(len(arrL))
y = int(len(arrR))
i = j = k = 0
while i < x and j < y:
if (arrL[i] <= arrR[j]):
arrN[k] = arrL[i]
i += 1
else:
arrN[k] = arrR[j]
j += 1
# end-if#001
k += 1
while (i < x):
arrN[k] = arrL[i]
i += 1
k += 1
while (j < y):
arrN[k] = arrR[j]
j += 1
k += 1
arr = arrN.copy()
print("Merged Array:" + str(arr))
return arrN
#End-if#001
return arrMain
I am having problems with my quicksort function constantly re cursing the best of three function. I dont know why it is doing that and i need help. I am trying to practice this for my coding class next semester and this is one of the assignments from last year that my friend had and im lost when it comes to this error
This is my quicksort function:
def quick_sort ( alist, function ):
if len(alist) <= 1:
return alist + []
pivot, index = function(alist)
#print("Pivot:",pivot)
left = []
right = []
for value in range(len(alist)):
if value == index:
continue
if alist[value] <= pivot:
left.append(alist[value])
else:
right.append(alist[value])
print("left:", left)
print("right:", right)
sortedleft = quick_sort( left, function )
print("sortedleft", sortedleft)
sortedright = quick_sort( right, function )
print("sortedright", sortedright)
completeList = sortedleft + [pivot] + sortedright
return completeList
#main
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
x = quick_sort(alist, best_of_three)
print(x)
this is my best of three function:
def best_of_three( bNlist, nine = False ):
rightindex = 2
middleindex = 1
if nine == False:
left = blist[0]
rightindex = int(len(blist) - 1)
rightvalue = int(blist[rightindex])
middleindex = int((len(blist) - 1)/2)
middlevalue = int(blist[middleindex])
bNlist.append(left)
bNlist.append(middlevalue)
bNlist.append(rightvalue)
BN = bNlist
print("Values:",BN)
left = bNlist[0]
middle = bNlist[1]
right = bNlist[2]
if left <= middle <= right:
return middle , middleindex
elif left >= middle >= right:
return middle, middleindex
elif middle <= right <= left:
return right, rightindex
elif middle >= right >= left:
return right, rightindex
else:
return left, 0
#main
bNlist = []
print('Best of Three')
blist = [54,26,93,17,77,31,44,55]
print("")
print( "List: [54,26,93,17,77,31,44,55]" )
x, index = best_of_three(bNlist)
print("Pivot: ",x)
print("----------------------------")
i really dont know why it keeps infinitely re cursing,
There is also a third function called ninther
def ninther( bNlist ):
stepsize = int(len(blist) / 9)
left = 0
middle = left + 2
right = left + 2 * stepsize
blist[left]
blist[middle]
blist[right]
leftvalue = blist[left]
rightvalue = blist[right]
middlevalue = blist[middle]
left2 = right + stepsize
middle2 = left2 + 2
right2 = left2 + 2 * stepsize
blist[left2]
blist[middle2]
blist[right2]
left2value = blist[left2]
middle2value = blist[middle2]
right2value = blist[right2]
left3 = right2 + stepsize
middle3 = left3 + 2
right3 = left3 + 2 * stepsize
blist[left3]
blist[middle3]
blist[right3]
left3value = blist[left3]
middle3value = blist[middle3]
right3value = blist[right3]
bN3list = []
bN2list = []
bNlist = []
bNlist.append(leftvalue)
bNlist.append(middlevalue)
bNlist.append(rightvalue)
bN2list.append(left2value)
bN2list.append(middle2value)
bN2list.append(right2value)
bN3list.append(left3value)
bN3list.append(middle3value)
bN3list.append(right3value)
BN3 = bN3list
BN2 = bN2list
BN = bNlist
print("Ninter ")
print("Group 1:", BN)
print("Group 2:", BN2)
print("Group 3:", BN3)
x = best_of_three(bNlist, True)[0]
c = best_of_three(bN2list, True)[0]
d = best_of_three(bN3list, True)[0]
print("Median 1:", x)
print("Median 2:", c)
print("Median 3:", d)
bN4list = [x,c,d]
print("All Medians:", bN4list)
z = best_of_three(bN4list, True)
return z[0], z[1]
#main
blist = [2, 6, 9, 7, 13, 4, 3, 5, 11, 1, 20, 12, 8, 10, 32, 16, 14, 17, 21, 46]
Y = ninther(blist)
print("Pivot", Y)
print("----------------------------")
i have looked everywhere in it and i cant figure out where the problem is when calling best of three
Summary: The main error causing infinite recursion is that you don't deal with the case where best_of_three receives a length 2 list. A secondary error is that best_of_three modifies the list you send to it. If I correct these two errors, as below, your code works.
The details: best_of_three([1, 2]) returns (2, 3), implying a pivot value of 2 at the third index, which is wrong. This would give a left list of [1, 2], which then causes exactly the same behavior at the next recursive quick_sort(left, function) call.
More generally, the problem is that the very idea of choosing the best index out of three possible values is impossible for a length 2 list, and you haven't chosen how to deal with that special case.
If I add this special case code to best_of_three, it deals with the length 2 case:
if len(bNlist) == 2:
return bNlist[1], 1
The function best_of_three also modifies bNlist. I have no idea why you have the lines of the form bNlist.append(left) in that function.
L = [15, 17, 17, 17, 17, 17, 17]
best_of_three(L)
print(L) # prints [15, 17, 17, 17, 17, 17, 17, 54, 17, 55]
I removed the append lines, since having best_of_three modify bNlist is unlikely to be what you want, and I have no idea why those lines are there. However, you should ask yourself why they are there to begin with. There might be some reason I don't know about. When I do that, there are a couple of quantities you compute that are never used, so I remove the lines that compute those also.
Then I notice you have the code
rightindex = 2
middleindex = 1
if nine == False:
rightindex = int(len(blist) - 1)
middleindex = int((len(blist) - 1)/2)
left = bNlist[0]
middle = bNlist[1]
right = bNlist[2]
This doesn't seem to make any sense, since you set rightindex and middleindex to other values, but then you still access values using the old indices (2 and 1 respectively). So I removed the if nine == False block. Again, ask yourself why you had this code to begin with, maybe there's some other way you should modify this to account for something I don't know about.
The result is the following for best_of_three:
def best_of_three(bNlist):
print(bNlist)
if len(bNlist) == 2:
return bNlist[1], 1
rightindex = 2
middleindex = 1
left = bNlist[0]
middle = bNlist[1]
right = bNlist[2]
if left <= middle <= right:
return middle , middleindex
elif left >= middle >= right:
return middle, middleindex
elif middle <= right <= left:
return right, rightindex
elif middle >= right >= left:
return right, rightindex
else:
return left, 0
If I use this, your code does not recurse infinitely, and it sorts.
I don't know why you mentioned ninther at all, since it seems to have nothing to do with your question. You should probably edit it to remove that code.