Skip to content

Added strand sort #1981

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 23 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions sorts/strand_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from functools import partial
import operator


def strand_sort(arr: list, solution: list, _operator: callable):
Copy link
Member

@cclauss cclauss May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sort would be easier to use (and test) if it returned a list instead of requiring the caller to allocate and pass in a solution list.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would also be cool if _operator was an optional parameter with the default set to operator.gt.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cclauss Could we move review to reopened PR: #1982? This PR was made by mistake.

"""
Strand sort implementation
source: https://en.wikipedia.org/wiki/Strand_sort

:param arr: Unordered input list
:param solution: Ordered output list
:param _operator: Operator lt/gt to specify ascent/descent version

Examples:
>>> solution_1 = []
>>> strand_sort([4, 2, 5, 3, 0, 1], solution_1, operator.gt)
>>> solution_1
[0, 1, 2, 3, 4, 5]

>>> solution_2 = []
>>> strand_sort([4, 2, 5, 3, 0, 1], solution_2, operator.lt)
>>> solution_2
[5, 4, 3, 2, 1, 0]
"""
if not arr:
return

sublist = [arr.pop(0)]
for i, item in enumerate(arr):
if _operator(item, sublist[-1]):
sublist.append(item)
arr.pop(i)

# merging sublist into solution list
if not solution:
solution.extend(sublist)
else:
while sublist:
item = sublist.pop(0)
for i, xx in enumerate(solution):
if not _operator(item, xx):
solution.insert(i, item)
break
else:
solution.append(item)

strand_sort(arr, solution, _operator)


strand_asc = partial(strand_sort, _operator=operator.gt)
strand_desc = partial(strand_sort, _operator=operator.lt)

if __name__ == "__main__":
solution = []
strand_asc([4, 3, 5, 1, 2], solution)
assert solution == [1, 2, 3, 4, 5]

solution = []
strand_desc([4, 3, 5, 1, 2], solution)
assert solution == [5, 4, 3, 2, 1]