Can someone help me to figure out what's wrong in my implementation of merge sort? - python-3.x

My implementation:
def merge_sort(arr):
if len(arr) <= 1:
return arr
left = arr[:len(arr)//2]
right = arr[len(arr)//2:]
merge_sort(left)
merge_sort(right)
return merge(left, right)
def merge(left, right):
leftI = rightI = 0
merged = []
while (leftI < len(left) and rightI < len(right)):
if left[leftI] < right[rightI]:
merged.append(left[leftI])
leftI += 1
else:
merged.append(right[rightI])
rightI += 1
merged.extend(left[leftI:])
merged.extend(right[rightI:])
return merged
if __name__ == '__main__':
arr = [1,2,5,5,9,22,6,3,6,8,1,43,5]
print(merge_sort(arr))
For some reason I am obtaining:
[1, 2, 5, 5, 6, 3, 6, 8, 1, 9, 22, 43, 5]
Working Implementation (Got from a friend):
def merge_sort(list):
list_length = len(list)
if list_length == 1:
return list
mid_point = list_length // 2
left_partition = merge_sort(list[:mid_point])
right_partition = merge_sort(list[mid_point:])
return merge(left_partition, right_partition)
def merge(left, right):
output = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
output.append(left[i])
i += 1
else:
output.append(right[j])
j += 1
output.extend(left[i:])
output.extend(right[j:])
return output
if __name__ == '__main__':
arr = [1,2,5,5,9,22,6,3,6,8,1,43,5]
print(merge_sort(arr))
This code yeilds:
[1, 1, 2, 3, 5, 5, 5, 6, 6, 8, 9, 22, 43]
I just can't figure out what's wrong. It'd be a great help if someone could take a few moments to help me out :)

In your merge_sort function, you do not change the values of left and right depending on what merge_sort returns.
You have :
merge_sort(left)
merge_sort(right)
Where it should be :
left = merge_sort(left)
right = merge_sort(right)

Related

I want to print all pairs with given sum k

def printPairs(arr, n, sum):
for i in range(0, n ):
for j in range(i + 1, n ):
if (arr[i] + arr[j] == sum):
print("(", arr[i], ", ", arr[j], ")", sep = "")
# Driver Code
arr = [1, 5, 7, -1, 5]
n = len(arr)
sum = 6
printPairs(arr, n, sum)
Does this look like it will do the job for you?
def printPairs (array, total) :
used = []
for number1 in array :
for number2 in array :
if number1 + number2 == total and number2 not in used :
print (f'({number1}, {number2})')
used.extend ([number1, number2])
test_array = [1, 5, 7, -1, 5]
# test_array = [4, 2, 1, 3, 6]
target = 6
printPairs (test_array, target)

Is there a way to properly continue this while loop?

I have written a function where the input is a list of numbers (items), where the length is a multiple of 3.
I want to this function to continue, until there is only 1 value left in items.
while len(items) > 1:
for x in range(0, len(items), 3):
if items[x] < items[x+1] < items[x+2] or items[x] > items[x+1] >items[x+2] :
result.append(items[x+1])
elif items[x+1] < items[x] < items[x+2] or items[x+1] > items[x] > items[x+2]:
result.append(items[x])
else:
result.append(items[x+2])
items = result
break
return items
Taking a guess at what you needed and how your code should appear...
items = [99, 42, 17, 7, 1, 9, 12, 77, 15]
while len(items) > 1:
result = []
for x in range(0, len(items), 3):
a, b, c = items[x], items[x+1], items[x+2]
if a < b < c or a > b >c :
result.append(b)
elif b < a < c or b > a > c:
result.append(a)
else:
result.append(c)
items = result
print(items)
Introducing the variables a, b, and c helped me better read the code.
The logic is not quite right. Imagine a simple input of [1, 1, 0]. By looking at this, the median should be 1 but the use of > and < instead of <= and >= end up with the code entering the final else block because 1<1 is False and 1>1 is also False. The final else block sets the result equal to the third element, which is 0.
Switch your operators to >= and <= to fix this. The break at the bottom of your for loop immediately breaks after one iteration, so that also needs to be removed.
If you have a list of one element (3**0 = 1), you will end up with an IndexError when you try to get the 2nd and 3rd elements in your loop.
So we need to
Switch operators to test for equality as well
Remove the erroneous break
Handle the base case
def median_split3(items):
if len(items) == 1: # Base Case
return items[0]
while len(items) > 1:
result = []
for x in range(0, len(items), 3):
a, b, c = items[x:x+3]
if a <= b <= c or a >= b >= c:
result.append(b)
elif b <= a <= c or b >= a >= c:
result.append(a)
else:
result.append(c)
items = result
return items[0]
test1 = [99, 42, 17, 7, 1, 9, 12, 77, 15]
print(test1, "-->", median_split3(test1))
test2 = [1, 1, 0]
print(test2, "-->", median_split3(test2))
test3 = [0, 0, 1]
print(test3, "-->", median_split3(test3))
test4 = [9]
print(test4, "-->", median_split3(test4))
Output:
[99, 42, 17, 7, 1, 9, 12, 77, 15] --> 15
[1, 1, 0] --> 1
[0, 0, 1] --> 0
[9] --> 9

CodingBat Python - List 2 sum(67)

Return the sum of the numbers in the array, except ignore sections of numbers starting with a 6 and extending to the next 7 (every 6 will be followed by at least one 7). Return 0 for no numbers.
Kindly Help me with the solution. For other input values i am getting correct output value.. and also suggest me a short way to write the code.. It seems bit too long
def sum67(nums):
count=0
i=0
switch = 0
if len(nums) == 0:
count=0
else:
while i < len(nums):
if nums[i] != 6 and switch == 0 and nums[i] != 7:
count += nums[i]
i+=1
#print("incremented")
continue
if nums[i] == 6 and switch == 0:
switch = 1
#print("switch ON")
i+=1
if nums[i] == 6 and switch == 1:
i+=1
if nums[i]==7 and switch==0 :
count+=nums[i]
#print("again 7")
i+=1
if switch == 1 and nums[i] == 7:
switch = 0
#print("switch OFF")
i+=1
else:
i+=1
#print(count)
return count
OUTPUT :
Input 1 : sum67([2, 7, 6, 2, 6, 7, 2, 7])
expected :18
output I got :20
Input 2 : sum67([2, 7, 6, 2, 6, 2, 7])
expected : 9
Output I got : 11
Try this:
def sum67(nums):
result = 0
startadding = True
for val in nums:
if val == 6:
startadding = False
if startadding:
result +=val
if val == 7:
startadding = True
return result
print(sum67([2, 7, 6, 2, 6, 7, 2, 7]))
This was my solution, I'm pretty new to programming, not sure if this is the correct way to do it but it works
def sum67(nums):
index = total = 0
while index < len(nums):
if nums[index] == 6:
while nums[index] != 7:
index += 1
index += 1
else:
total += nums[index]
index += 1
return total
Here is a solution
def sum67(nums):
total_sum = 0
skip_flag = False
for number in nums:
if number == 6:
skip_flag = True # prepare to skip
continue # skip this iteration
if number == 7 and skip_flag == True:
skip_flag = False # prepare to sum
continue # skip this iteration
if skip_flag == False:
total_sum += number
return total_sum
testing:
>>>sum67([2, 7, 6, 2, 6, 7, 2, 7]) # -> 18
>>>sum67([2, 7, 6, 2, 6, 2, 7])) # -> 9
Here is the simplest solution:
def sum67(nums):
while 6 in nums:
del nums[nums.index(6):nums.index(7,nums.index(6))+1]
return sum(nums)
Here's a far simpler solution:
def sum67(nums):
my_sum = 0
do_sum = True
for num in nums:
if num == 6:
# stop summing
do_sum = False
elif num == 7:
# start summing
do_sum = True
# if we were not summing then this 7 will be added to the sum, so subtract it now to keep the sum correct
if not do_sum:
my_sum -= 7
if do_sum:
my_sum += num
return my_sum
print(sum67([2, 7, 6, 2, 6, 7, 2, 7])) # 18
print(sum67([2, 7, 6, 2, 6, 2, 7])) # 9
List-2 > sum67(python3)
def sum67(nums):
s = sum(nums)
l=[0]
for i in range(len(nums)):
if nums[i]==6 and nums[l[-1]]!=6:
l.append(i)
if nums[i]==7 and nums[l[-1]]==6:
l.append(i)
s-=sum(nums[l[-2]:l[-1]+1])
return s
def sum67(nums):
soma = 0
if (len(nums)>0):
i =0
while i<len(nums):
if (nums[i] == 6):
while (nums[i] != 7):
i +=1
else : soma += nums[i]
i +=1
return soma
else : return 0
def except6_7(nums):
if nums.count(6) == 1 and nums.count(7) == 1:
return sum(nums)-sum(nums[nums.index(6):nums.index(7)+1])
return sum(nums)
print(except6_7([1, 2, 2, 6, 99, 99, 7]))
or
def except6_7(nums):
while 6 and 7 in nums: ## YOU MUST ADD "and 7" ##
del nums[nums.index(6):nums.index(7,nums.index(6))+1]
return sum(nums)
print(except6_7([1, 2, 2, 6, 99, 99]))
def sum67(nums):
my_sum = 0
do_sum = True
for num in nums:
if num == 6:
# stop summing
do_sum = False
elif num == 7 and do_sum == False:
# start summing
do_sum = True
my_sum -= 7
if do_sum:
my_sum += num
return my_sum
print(sum67([2, 7, 4, 3, 6, 67, 45, 7, 2])) # gives output of 18
print(sum67([1, 2, 2, 6, 99, 99, 7]) # gives output 5 (both correct)
# I didn't have enough contributor points to reply to the guy who had an error in his and this is a correction of that
def sum67(nums):
sum_= sum(nums)
six = [i for i, x in enumerate(nums) if x == 6]
seven = [i for i, x in enumerate(nums) if x == 7]
seven = [x for x in seven if x>six[0]]
tmp = []
if six:
if len(six)>len(seven):
six = six[::2]
for i in range(len(six)):
sum_-=sum(nums[six[i]:seven[i]+1])
return sum_
elif len(six)<len(seven):
seven = seven[:len(six)]
for i in range(len(seven)):
sum_-=sum(nums[six[i]:seven[i]+1])
return sum_
else:
for i in range(len(six)-1):
if six[i+1]<seven[i]:
tmp.append(six[i+1])
if tmp:
for i in range(len(tmp)):
six.remove(tmp[i])
for i in range(len(six)):
sum_-=sum(nums[six[i]:seven[i]+1])
return sum_
else:
for i in range(len(seven)):
sum_-=sum(nums[six[i]:seven[i]+1])
return sum_
else:
return sum(nums)

Euler Project 111 Code to make shorter and shorter

I am solving Euler Project # 111 problem, and the code I wrote is running for too long. How can I write this shorter, simpler, faster?
The problem is the link
https://projecteuler.net/problem=111
result = 0
a = []
count_number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
for i in range(1000000000, 9999999999):
if i == 2:
result += i
for j in range(1000000000, i):
if i % j == 0:
break
elif j == i -1:
a = list(str(i))
for k in range(len(count_number)):
if a.count(count_number[k]) == 1:
break
elif a.count(count_number[k] == count_number[k]):
result += i
del a
print(result)

primitive calculator Second step,

I try to get the code right for the minimum required steps to get to n and the subsequent list, steps are multiply by 2 or 3, or add 1. It should be implemented through dynamic programming since using greedy choices for this one is unsafe. First I got the minimum steps required using the following code, it works just fine .
What I can't get is how do I go about unpacking that list, please I don't need answers, this is an assignment for an online class, hints or Help is Ok, so I try to maintain my moral integrity here.
def optimal_sequence(n):
sequence = [0]*(n+1)
for i in range(2, n+1):
if i % 3 == 0:
sequence[i] = sequence[(i // 3)]+1
if sequence[i] - sequence[i-1] <= 1:
sequence[i] = sequence[i]
else:
sequence[i] = sequence[i-1] + 1
elif i % 2 == 0:
sequence[i] = sequence[(i // 2)]+1
if sequence[i] - sequence[i-1] <= 1:
sequence[i] = sequence[i]
else:
sequence[i] = sequence[i-1] + 1
else:
sequence[i] = sequence[i-1] + 1
return sequence
while n >= 1:
seq.append(n)
if n % 3 == 0 and sequence[n] != sequence[n//3]: n = n // 3
elif n % 2 == 0 and sequence[n] != sequence[n//2]: n = n // 2
else: n = n-1
seq.reverse(); return seq
Here is how it maps the minimum number for let's say n = 28,
n = 28
print(optimal_sequence(n))
>>> [0, 0, 1, 1, 2, 3, 2, 3, 3, 2, 3, 4, 3, 4, 4, 4, 4, 5, 3, 4, 4, 4, 5, 6, 4, 5, 5, 3, 4]
Now, if you can help me see if the code is right for the first part, if it is, then what is wrong with the second part of it beginning with while.
Thanks

Resources