I am trying to write and optimized bubble sort, but my code does not actually sort right through the list. Any suggestions as to why it is stopping early?
#!/usr/bin/env python
from random import *
import time
def bubble(lst):
counter = 0
n = len(lst)
while n > 0:
temp = 0
for i in range(1, n - 1):
if lst[i] > lst[i + 1]:
lst[i], lst[i + 1] = lst[i + 1], lst[i] # swap
temp = i
counter += 1 # to compare the speed to the
# unoptimized bubble sort
n = temp
return counter
def main():
lst = range(10)
shuffle(lst)
print lst
start = time.time()
counter = bubble(lst)
print lst
end = time.time()
print counter
print "time", end - start
main()
This should fix it:
def bubble(lst):
counter = 0
n = len(lst)
while n > 0:
temp = 0
for i in range(0,n-1): # <- first element is at position 0
if lst[i] > lst[i+1]:
lst[i],lst[i+1] = lst[i+1],lst[i] #swap
temp = i+1 # <- the last swapped position
counter += 1
n = temp
return counter
Related
How can i find the Largest sum consecutive increasing digits and its position in a Number using python ?
Here is my approach :
def findLIS(A, n):
hash = dict()
LIS_size, LIS_index = 1, 0
hash[A[0]] = 1
for i in range(1, n):
if A[i] - 1 not in hash:
hash[A[i] - 1] = 0
hash[A[i]] = hash[A[i] - 1] + 1
if LIS_size < hash[A[i]]:
LIS_size = hash[A[i]]
LIS_index = A[i]
start = LIS_index - LIS_size + 1
while start <= LIS_index:
# print(start, end = " ")
z.insert(i - 1,start)
start += 1
print(z[~0])
print(sum(z))
# Driver Code
if __name__ == "__main__":
num = input()
A = [int(x) for x in str(num)]
n = len(A)
z=[]
findLIS(A, n)
Solution:
n = input()+"0"
max_sum = 0
max_pos = ""
start = 0
sum = int(n[0])
for i in range(1, len(n)):
if n[i-1] >= n[i]:
if max_sum < sum:
max_sum = sum
max_pos = "{}-{}".format(start+1, i)
start = i
sum = int(n[i])
else:
sum += int(n[i])
print("{}:{}".format(max_sum, max_pos))
There is numbers should strictly increase. If sequence 333 also match your condition that you need to change condition: if n[i-1] > n[i]:
Here is my solution to a merge sort in python.
My notes:
The time is 2n(log(n)) instead of n(log(n)) because of the stack in recursion. I can't see any way to fix this.
A bottom up recursion method is actually easier and is n(log(n))
I have seen my solution that use slicing. For example:
lefthalf = alist[:mid]
righthalf = alist[mid:]
mergeSort(lefthalf)
mergeSort(righthalf)
However, these solutions ignore that a slice takes k time, because a slice takes k times. So the above code actually is:
lefthalf = []
for i in range(mid): #k times
lefhalf.append(alist[i])
for i in range(mid, len(alist): #k times
righthalf.append(alist[i])
My solution:
import random
def _merge_sort(indices, the_list):
start = indices[0]
end = indices[1]
half_way = (end - start)//2 + start
if start < half_way:
_merge_sort((start, half_way), the_list)
if half_way + 1 <= end and end - start != 1:
_merge_sort((half_way + 1, end), the_list)
#a stack is created using log(n) number of recursions
sort_sub_list(the_list, indices[0], indices[1])
def sort_sub_list(the_list, start, end):
orig_start = start
initial_start_second_list = (end - start)//2 + start + 1
list2_first_index = initial_start_second_list
new_list = []
while start < initial_start_second_list and list2_first_index <= end:
first1 = the_list[start]
first2 = the_list[list2_first_index]
if first1 > first2:
new_list.append(first2)
list2_first_index += 1
else:
new_list.append(first1)
start += 1
while start < initial_start_second_list:
new_list.append(the_list[start])
start += 1
while list2_first_index <= end:
new_list.append(the_list[list2_first_index])
list2_first_index += 1
# at this point, the total number each while statement ran is n
# now we have to do n again!
for i in new_list:
the_list[orig_start] = i
orig_start += 1
def merge_sort(the_list):
return _merge_sort((0, len(the_list) - 1), the_list)
if __name__ == '__main__':
for i in range(100):
n = 100
l = range(n)
random.shuffle(l)
merge_sort(l)
assert l == range(n)
I have the following implementation of a Counting Sort algorithm in Python, but it doesn't work with arrays that contains negative numbers. Could someone help me?
def counting(nlist):
nlist = list(nlist)
size = len(nlist)
if size < 2:
return nlist
k = max(nlist)
counter = [0] * ( k + 1 )
for i in nlist:
counter[i] += 1
ndx = 0;
for i in range( len( counter ) ):
while 0 < counter[i]:
nlist[ndx] = i
ndx += 1
counter[i] -= 1
return nlist
A simple approach would be just to find the minimum value and offset your indices by that amount, so that the minimum value is stored in array index 0 of counter. Then in your while loop, add the minimum value back on to get the original values:
m = min(nlist)
k = max(nlist) - m
counter = [0] * ( k + 1 )
for i in nlist:
counter[i-m] += 1
ndx = 0;
for i in range( len( counter ) ):
while 0 < counter[i]:
nlist[ndx] = i+m
ndx += 1
counter[i] -= 1
You could look up the lowest value in your input, and add that to your index all the way, converting it back when your build the output:
def counting(nlist):
nlist = list(nlist)
size = len(nlist)
if size < 2:
return nlist
low = min(nlist)
k = max(nlist) - low
counter = [0] * ( k + 1 )
for i in nlist:
counter[i - low] += 1
print(counter) # see what the counter list looks like. Remove in final version
ndx = 0;
for i in range( len( counter ) ):
while 0 < counter[i]:
nlist[ndx] = i + low
ndx += 1
counter[i] -= 1
return nlist
I have a two dimensional list that I have to sort and I have to only use while loops. So far my code does not work for all lists.
def sort(list):
i = 0
j = 0
while i < len(list):
while j < len(list[i]) - 1:
if list[i][j] > list[i][j + 1]:
temp = list[i][j]
list[i][j] = list[i][j + 1]
list[i][j + 1] = temp
j += 1
j = 0
i += 1
return list
sort([[3,5,2,8,6,9],[9,1,2,5]])
This code still has numbers out of order. Is there a better way to sort?
Your inner loop takes only one pass through the list. This guarantees that the largest element is at the end, but doesn't necessarily do anythign else. You need to add a loop to continue while you still have unfinished business.
I left in the tracing statements I used to highlight the problem, as well as the simple reverse-order case.
def sort(list):
i = 0
j = 0
while i < len(list):
done = False
while not done:
done = True
while j < len(list[i]) - 1:
print i, j, list[i][j], list[i][j + 1]
if list[i][j] > list[i][j + 1]:
temp = list[i][j]
list[i][j] = list[i][j + 1]
list[i][j + 1] = temp
done = False
print "SWAP", list[i]
j += 1
j = 0
i += 1
return list
print sort([[6, 5, 4, 3, 2, 1, 0]])
print sort([[3,5,2,8,6,9],[9,1,2,5]])
I'm trying to make a function that sorts a list using bubble sorting and returns a tuple with the number of swaps and comparisons. Such that:
print(perform_bubble_sort([3, 5, 7]))
>>> (3, 0)
.
I tried using the following code but it doesn't return the right number of comparisons for some reason.
def perform_bubble_sort(blist):
cmpcount, swapcount = 0, 0
while True:
swapped = False
for i in range(1, len(blist)):
cmpcount += 1
if blist[i-1] > blist[i]:
swapcount += 1
blist[i-1], blist[i] = blist[i], blist[i-1]
swapped = True
if not swapped:
break
return cmpcount, swapcount
def perform_bubble_sort(blist):
cmpcount, swapcount = 0, 0
for j in range(len(blist)):
for i in range(1, len(blist)-j):
cmpcount += 1
if blist[i-1] > blist[i]:
swapcount += 1
blist[i-1], blist[i] = blist[i], blist[i-1]
return cmpcount, swapcount
You don't need to iterate over blist every time
def queue(lst):
n = len(lst)
swipe_count = 0
for i in range(n):
for j in range(n - i - 1):
if lst[j] > lst[j + 1]:
lst[j], lst[j + 1] = lst[j + 1], lst[j]
swipe_count += 1
return lst, swipe_count