From 0a0fe917ddbeaaf2fc93a869b1986544b8e41d28 Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 00:51:49 +0200 Subject: [PATCH 01/11] Adding variable to fade out ambiguity --- sorts/insertion_sort.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sorts/insertion_sort.py b/sorts/insertion_sort.py index 59917ac059a7..e088705947d4 100644 --- a/sorts/insertion_sort.py +++ b/sorts/insertion_sort.py @@ -29,10 +29,12 @@ def insertion_sort(collection): >>> insertion_sort([-2, -5, -45]) [-45, -5, -2] """ - for index in range(1, len(collection)): - while index > 0 and collection[index - 1] > collection[index]: - collection[index], collection[index - 1] = collection[index - 1], collection[index] - index -= 1 + + for loop_index in range(1, len(collection)): + insertion_index = loop_index + while insertion_index > 0 and collection[insertion_index - 1] > collection[insertion_index]: + collection[insertion_index], collection[insertion_index - 1] = collection[insertion_index - 1], collection[insertion_index] + insertion_index -= 1 return collection From 4aa9ea9f5bce4d1985567fde50025b1b49d65765 Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 01:26:50 +0200 Subject: [PATCH 02/11] More readability on merge sorting algorithm --- sorts/merge_sort.py | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/sorts/merge_sort.py b/sorts/merge_sort.py index ca4d319fa7f1..8f03ee48a851 100644 --- a/sorts/merge_sort.py +++ b/sorts/merge_sort.py @@ -30,33 +30,27 @@ def merge_sort(collection): [-45, -5, -2] """ length = len(collection) - if length > 1: - midpoint = length // 2 - left_half = merge_sort(collection[:midpoint]) - right_half = merge_sort(collection[midpoint:]) - i = 0 - j = 0 - k = 0 - left_length = len(left_half) - right_length = len(right_half) - while i < left_length and j < right_length: - if left_half[i] < right_half[j]: - collection[k] = left_half[i] - i += 1 - else: - collection[k] = right_half[j] - j += 1 - k += 1 + if length <= 1: + return collection - while i < left_length: - collection[k] = left_half[i] - i += 1 - k += 1 + sorted_result = [] + midpoint = length // 2 + left_half_sorted = merge_sort(collection[:midpoint]) + right_half_sorted = merge_sort(collection[midpoint:]) + while len(left_half_sorted) > 0 and len(right_half_sorted) > 0: + min_element = ( + left_half_sorted.pop(0) if left_half_sorted[0] <= right_half_sorted[0] + else right_half_sorted.pop(0) + ) + sorted_result.append(min_element) - while j < right_length: - collection[k] = right_half[j] - j += 1 - k += 1 + # If there is some remaining elements, they should be added into the sorted collection's end + remaining_elements = left_half_sorted if len(left_half_sorted) > 0 else right_half_sorted + sorted_result += remaining_elements + + # For more generic algorithm, making sure that the output and input types are the same + for index, element in enumerate(sorted_result): + collection[index] = element return collection From affd6a0f0cc5363c5c365a881d0b032e26e1e61f Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 01:32:54 +0200 Subject: [PATCH 03/11] Updating merge_sort_fastest description and explaining why --- sorts/merge_sort_fastest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorts/merge_sort_fastest.py b/sorts/merge_sort_fastest.py index 9fc9275aacba..d28967c816b4 100644 --- a/sorts/merge_sort_fastest.py +++ b/sorts/merge_sort_fastest.py @@ -2,7 +2,7 @@ Python implementation of merge sort algorithm. Takes an average of 0.6 microseconds to sort a list of length 1000 items. Best Case Scenario : O(n) -Worst Case Scenario : O(n) +Worst Case Scenario : O(n^2) because native python functions:min, max and remove are already O(n) ''' def merge_sort(LIST): start = [] From e04800bac13749116907c90e438c487bf7b731e3 Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 01:56:16 +0200 Subject: [PATCH 04/11] Adding tests file with imports --- sorts/tests.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 sorts/tests.py diff --git a/sorts/tests.py b/sorts/tests.py new file mode 100644 index 000000000000..3251a32b2ca3 --- /dev/null +++ b/sorts/tests.py @@ -0,0 +1,23 @@ +from bogosort import bogosort +from bubble_sort import bubble_sort +from bucket_sort import bucketSort +from cocktail_shaker_sort import cocktail_shaker_sort +from comb_sort import comb_sort +from counting_sort import counting_sort +from cyclesort import cycle_sort +from gnome_sort import gnome_sort +from heap_sort import heap_sort +from insertion_sort import insertion_sort +from merge_sort_fastest import merge_sort as merge_sort_fastest +from merge_sort import merge_sort +from pancake_sort import pancake_sort +from quick_sort_3_partition import quick_sort_3partition +from quick_sort import quick_sort +from radix_sort import radixsort +from random_pivot_quick_sort import quick_sort_random +from selection_sort import selection_sort +from shell_sort import shell_sort +from timsort import timsort +from topological_sort import topological_sort +from tree_sort import treesort +from wiggle_sort import wiggle_sort From 23a05277c0e6dd55a3d4987fb88ae186d07798ec Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 02:01:59 +0200 Subject: [PATCH 05/11] Standardazing filenames and function names --- sorts/{bogosort.py => bogo_sort.py} | 16 ++++++++-------- sorts/bucket_sort.py | 4 ++-- sorts/{cyclesort.py => cycle_sort.py} | 0 sorts/pancake_sort.py | 4 ++-- sorts/radix_sort.py | 2 +- sorts/tests.py | 12 ++++++------ sorts/{timsort.py => tim_sort.py} | 4 ++-- sorts/tree_sort.py | 4 ++-- 8 files changed, 23 insertions(+), 23 deletions(-) rename sorts/{bogosort.py => bogo_sort.py} (81%) rename sorts/{cyclesort.py => cycle_sort.py} (100%) rename sorts/{timsort.py => tim_sort.py} (97%) diff --git a/sorts/bogosort.py b/sorts/bogo_sort.py similarity index 81% rename from sorts/bogosort.py rename to sorts/bogo_sort.py index 33eac66bf21c..056e8e68a92e 100644 --- a/sorts/bogosort.py +++ b/sorts/bogo_sort.py @@ -1,28 +1,28 @@ """ This is a pure python implementation of the bogosort algorithm For doctests run following command: -python -m doctest -v bogosort.py +python -m doctest -v bogo_sort.py or -python3 -m doctest -v bogosort.py +python3 -m doctest -v bogo_sort.py For manual testing run: -python bogosort.py +python bogo_sort.py """ from __future__ import print_function import random -def bogosort(collection): +def bogo_sort(collection): """Pure implementation of the bogosort algorithm in Python :param collection: some mutable ordered collection with heterogeneous comparable items inside :return: the same collection ordered by ascending Examples: - >>> bogosort([0, 5, 3, 2, 2]) + >>> bogo_sort([0, 5, 3, 2, 2]) [0, 2, 2, 3, 5] - >>> bogosort([]) + >>> bogo_sort([]) [] - >>> bogosort([-2, -5, -45]) + >>> bogo_sort([-2, -5, -45]) [-45, -5, -2] """ @@ -46,4 +46,4 @@ def isSorted(collection): user_input = raw_input('Enter numbers separated by a comma:\n').strip() unsorted = [int(item) for item in user_input.split(',')] - print(bogosort(unsorted)) + print(bogo_sort(unsorted)) diff --git a/sorts/bucket_sort.py b/sorts/bucket_sort.py index bd4281e463eb..ae7a9d627bcc 100644 --- a/sorts/bucket_sort.py +++ b/sorts/bucket_sort.py @@ -19,7 +19,7 @@ DEFAULT_BUCKET_SIZE = 5 -def bucketSort(myList, bucketSize=DEFAULT_BUCKET_SIZE): +def bucket_sort(myList, bucketSize=DEFAULT_BUCKET_SIZE): if(len(myList) == 0): print('You don\'t have any elements in array!') @@ -53,5 +53,5 @@ def bucketSort(myList, bucketSize=DEFAULT_BUCKET_SIZE): return sortedArray if __name__ == '__main__': - sortedArray = bucketSort([12, 23, 4, 5, 3, 2, 12, 81, 56, 95]) + sortedArray = bucket_sort([12, 23, 4, 5, 3, 2, 12, 81, 56, 95]) print(sortedArray) diff --git a/sorts/cyclesort.py b/sorts/cycle_sort.py similarity index 100% rename from sorts/cyclesort.py rename to sorts/cycle_sort.py diff --git a/sorts/pancake_sort.py b/sorts/pancake_sort.py index 26fd40b7f67c..7c5ced924465 100644 --- a/sorts/pancake_sort.py +++ b/sorts/pancake_sort.py @@ -1,7 +1,7 @@ # Pancake sort algorithm # Only can reverse array from 0 to i -def pancakesort(arr): +def pancake_sort(arr): cur = len(arr) while cur > 1: # Find the maximum number in arr @@ -13,4 +13,4 @@ def pancakesort(arr): cur -= 1 return arr -print(pancakesort([0,10,15,3,2,9,14,13])) +print(pancake_sort([0,10,15,3,2,9,14,13])) diff --git a/sorts/radix_sort.py b/sorts/radix_sort.py index e4cee61f35e3..8dfc66b17b23 100644 --- a/sorts/radix_sort.py +++ b/sorts/radix_sort.py @@ -1,4 +1,4 @@ -def radixsort(lst): +def radix_sort(lst): RADIX = 10 placement = 1 diff --git a/sorts/tests.py b/sorts/tests.py index 3251a32b2ca3..0caccbc68417 100644 --- a/sorts/tests.py +++ b/sorts/tests.py @@ -1,10 +1,10 @@ -from bogosort import bogosort +from bogo_sort import bogo_sort from bubble_sort import bubble_sort -from bucket_sort import bucketSort +from bucket_sort import bucket_sort from cocktail_shaker_sort import cocktail_shaker_sort from comb_sort import comb_sort from counting_sort import counting_sort -from cyclesort import cycle_sort +from cycle_sort import cycle_sort from gnome_sort import gnome_sort from heap_sort import heap_sort from insertion_sort import insertion_sort @@ -13,11 +13,11 @@ from pancake_sort import pancake_sort from quick_sort_3_partition import quick_sort_3partition from quick_sort import quick_sort -from radix_sort import radixsort +from radix_sort import radix_sort from random_pivot_quick_sort import quick_sort_random from selection_sort import selection_sort from shell_sort import shell_sort -from timsort import timsort +from tim_sort import tim_sort from topological_sort import topological_sort -from tree_sort import treesort +from tree_sort import tree_sort from wiggle_sort import wiggle_sort diff --git a/sorts/timsort.py b/sorts/tim_sort.py similarity index 97% rename from sorts/timsort.py rename to sorts/tim_sort.py index 80c5cd1e8d3f..b4032b91aec1 100644 --- a/sorts/timsort.py +++ b/sorts/tim_sort.py @@ -41,7 +41,7 @@ def merge(left, right): return [right[0]] + merge(left, right[1:]) -def timsort(lst): +def tim_sort(lst): runs, sorted_runs = [], [] length = len(lst) new_run = [lst[0]] @@ -75,7 +75,7 @@ def timsort(lst): def main(): lst = [5,9,10,3,-4,5,178,92,46,-18,0,7] - sorted_lst = timsort(lst) + sorted_lst = tim_sort(lst) print(sorted_lst) if __name__ == '__main__': diff --git a/sorts/tree_sort.py b/sorts/tree_sort.py index f8ecf84c6ff8..d50bbd3d78e0 100644 --- a/sorts/tree_sort.py +++ b/sorts/tree_sort.py @@ -30,7 +30,7 @@ def inorder(root, res): res.append(root.val) inorder(root.right,res) -def treesort(arr): +def tree_sort(arr): # Build BST if len(arr) == 0: return arr @@ -42,4 +42,4 @@ def treesort(arr): inorder(root,res) return res -print(treesort([10,1,3,2,9,14,13])) \ No newline at end of file +print(tree_sort([10,1,3,2,9,14,13])) From abba6a0bcd63fe54c534bfb699225180e0737f8e Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 02:10:30 +0200 Subject: [PATCH 06/11] Adding test cases and test functions --- sorts/tests.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/sorts/tests.py b/sorts/tests.py index 0caccbc68417..357326c2deda 100644 --- a/sorts/tests.py +++ b/sorts/tests.py @@ -21,3 +21,37 @@ from topological_sort import topological_sort from tree_sort import tree_sort from wiggle_sort import wiggle_sort + + +TEST_CASES = [ + {'input': [8, 7, 6, 5, 4, 3, -2, -5], 'expected': [-5, -2, 3, 4, 5, 6, 7, 8]}, + {'input': [-5, -2, 3, 4, 5, 6, 7, 8], 'expected': [-5, -2, 3, 4, 5, 6, 7, 8]}, + {'input': [5, 6, 1, 4, 0, 1, -2, -5, 3, 7], 'expected': [-5, -2, 0, 1, 1, 3, 4, 5, 6, 7]}, +] + + +TEST_FUNCTIONS = [ + bogo_sort, + bubble_sort, + bucket_sort, + cocktail_shaker_sort, + comb_sort, + counting_sort, + cycle_sort, + gnome_sort, + heap_sort, + insertion_sort, + merge_sort_fastest, + merge_sort, + pancake_sort, + quick_sort_3partition, + quick_sort, + radix_sort, + quick_sort_random, + selection_sort, + shell_sort, + tim_sort, + topological_sort, + tree_sort, + wiggle_sort, +] From 31362cbd22fba32d896d75cd71c5f7b39a7c7c3d Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 02:12:02 +0200 Subject: [PATCH 07/11] Adding test loop --- sorts/tests.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sorts/tests.py b/sorts/tests.py index 357326c2deda..62b6fa95169b 100644 --- a/sorts/tests.py +++ b/sorts/tests.py @@ -55,3 +55,8 @@ tree_sort, wiggle_sort, ] + + +for function in TEST_FUNCTIONS: + for case in TEST_CASES: + assert function(case['input']) == case['expected'] From 76ed0f81434426c65232987cb629e79411475d8c Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 02:13:52 +0200 Subject: [PATCH 08/11] Putting 'user oriented code' inside main condition for having valid imports --- sorts/cycle_sort.py | 16 ++++++++-------- sorts/pancake_sort.py | 3 ++- sorts/topological_sort.py | 6 +++--- sorts/tree_sort.py | 3 ++- sorts/wiggle_sort.py | 18 ++++++++---------- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/sorts/cycle_sort.py b/sorts/cycle_sort.py index ee19a1ade360..492022164427 100644 --- a/sorts/cycle_sort.py +++ b/sorts/cycle_sort.py @@ -50,11 +50,11 @@ def cycle_sort(array): except NameError: raw_input = input # Python 3 -user_input = raw_input('Enter numbers separated by a comma:\n') -unsorted = [int(item) for item in user_input.split(',')] -n = len(unsorted) -cycle_sort(unsorted) - -print("After sort : ") -for i in range(0, n): - print(unsorted[i], end=' ') + user_input = raw_input('Enter numbers separated by a comma:\n') + unsorted = [int(item) for item in user_input.split(',')] + n = len(unsorted) + cycle_sort(unsorted) + + print("After sort : ") + for i in range(0, n): + print(unsorted[i], end=' ') diff --git a/sorts/pancake_sort.py b/sorts/pancake_sort.py index 7c5ced924465..478a9a967d27 100644 --- a/sorts/pancake_sort.py +++ b/sorts/pancake_sort.py @@ -13,4 +13,5 @@ def pancake_sort(arr): cur -= 1 return arr -print(pancake_sort([0,10,15,3,2,9,14,13])) +if __name__ == '__main__': + print(pancake_sort([0,10,15,3,2,9,14,13])) diff --git a/sorts/topological_sort.py b/sorts/topological_sort.py index 52dc34f4f733..db4dd250a119 100644 --- a/sorts/topological_sort.py +++ b/sorts/topological_sort.py @@ -28,6 +28,6 @@ def topological_sort(start, visited, sort): # return sort return sort - -sort = topological_sort('a', [], []) -print(sort) +if __name__ == '__main__': + sort = topological_sort('a', [], []) + print(sort) diff --git a/sorts/tree_sort.py b/sorts/tree_sort.py index d50bbd3d78e0..d06b0de28e56 100644 --- a/sorts/tree_sort.py +++ b/sorts/tree_sort.py @@ -42,4 +42,5 @@ def tree_sort(arr): inorder(root,res) return res -print(tree_sort([10,1,3,2,9,14,13])) +if __name__ == '__main__': + print(tree_sort([10,1,3,2,9,14,13])) diff --git a/sorts/wiggle_sort.py b/sorts/wiggle_sort.py index cc83487bdeb1..0d4f20e3f96b 100644 --- a/sorts/wiggle_sort.py +++ b/sorts/wiggle_sort.py @@ -9,13 +9,11 @@ def wiggle_sort(nums): if (i % 2 == 1) == (nums[i-1] > nums[i]): nums[i-1], nums[i] = nums[i], nums[i-1] - -print("Enter the array elements:\n") -array=list(map(int,input().split())) -print("The unsorted array is:\n") -print(array) -wiggle_sort(array) -print("Array after Wiggle sort:\n") -print(array) - - +if __name__ == '__main__': + print("Enter the array elements:\n") + array=list(map(int,input().split())) + print("The unsorted array is:\n") + print(array) + wiggle_sort(array) + print("Array after Wiggle sort:\n") + print(array) From 4d323f977c3e61ad1d2ef0ab1f74f541e30ea543 Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 02:15:35 +0200 Subject: [PATCH 09/11] Fixing condition --- sorts/bucket_sort.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorts/bucket_sort.py b/sorts/bucket_sort.py index ae7a9d627bcc..c19b239e3c0c 100644 --- a/sorts/bucket_sort.py +++ b/sorts/bucket_sort.py @@ -21,7 +21,7 @@ def bucket_sort(myList, bucketSize=DEFAULT_BUCKET_SIZE): if(len(myList) == 0): - print('You don\'t have any elements in array!') + return myList minValue = myList[0] maxValue = myList[0] From ed5bfaaa73d19c8100f6d548b92265bb946f144d Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 02:35:15 +0200 Subject: [PATCH 10/11] Updating tests: adding cases and todo list --- sorts/tests.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sorts/tests.py b/sorts/tests.py index 62b6fa95169b..225763625f51 100644 --- a/sorts/tests.py +++ b/sorts/tests.py @@ -27,8 +27,19 @@ {'input': [8, 7, 6, 5, 4, 3, -2, -5], 'expected': [-5, -2, 3, 4, 5, 6, 7, 8]}, {'input': [-5, -2, 3, 4, 5, 6, 7, 8], 'expected': [-5, -2, 3, 4, 5, 6, 7, 8]}, {'input': [5, 6, 1, 4, 0, 1, -2, -5, 3, 7], 'expected': [-5, -2, 0, 1, 1, 3, 4, 5, 6, 7]}, + {'input': [2, -2], 'expected': [-2, 2]}, + {'input': [1], 'expected': [1]}, + {'input': [], 'expected': []}, ] +''' + TODO: + - Fix some broken tests in particular cases (as [] for example), + - Unify the input format: should always be function(input_collection) (no additional args) + - Unify the output format: should always be a collection instead of updating input elements + and returning None + - Rewrite some algorithms in function format (in case there is no function definition) +''' TEST_FUNCTIONS = [ bogo_sort, @@ -59,4 +70,5 @@ for function in TEST_FUNCTIONS: for case in TEST_CASES: - assert function(case['input']) == case['expected'] + result = function(case['input']) + assert result == case['expected'], 'Executed function: {}, {} != {}'.format(function.__name__, result, case['expected']) From a51208088f1e9fa2903d380ec4f5ac0897b5600d Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Sun, 5 May 2019 02:45:45 +0200 Subject: [PATCH 11/11] Refactoring first euler problem's first solution --- project_euler/problem_01/sol1.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/project_euler/problem_01/sol1.py b/project_euler/problem_01/sol1.py index 27031c3cfa9a..c9a8c0f1ebeb 100644 --- a/project_euler/problem_01/sol1.py +++ b/project_euler/problem_01/sol1.py @@ -10,8 +10,4 @@ except NameError: raw_input = input # Python 3 n = int(raw_input().strip()) -sum=0 -for a in range(3,n): - if(a%3==0 or a%5==0): - sum+=a -print(sum) +print(sum([e for e in range(3, n) if e % 3 == 0 or e % 5 == 0]))