Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ohaval/88e79eaca1d2c712bcebf3614a58bfa5 to your computer and use it in GitHub Desktop.
Save ohaval/88e79eaca1d2c712bcebf3614a58bfa5 to your computer and use it in GitHub Desktop.
An implementation of the Ford-Johnson Algorithm for a 5 integer list in Python, which sorts in 7 comparisons only
"""As part of the 'Data Structures and Introduction to Algorithms' course, I was asked to solve the following problem:
Write a function that sorts five elements in seven comparisons in the worst case.
As I found this problem interesting, I decided to implement it in Python. For better understanding, I recommend
reading the answer from the link below, which explains the algorithm.
"""
import random
from typing import List
def sort_five_elements_in_seven_comparisons(numbers: List[int]) -> List[int]:
"""
Based on "Ford-Johnson Algorithm" and this answer: https://stackoverflow.com/a/1935353/11808461
"""
sublist_1 = [numbers[0], numbers[1]]
sublist_2 = [numbers[2], numbers[3]]
if sublist_1[0] > sublist_1[1]:
sublist_1[0], sublist_1[1] = sublist_1[1], sublist_1[0]
if sublist_2[0] > sublist_2[1]:
sublist_2[0], sublist_2[1] = sublist_2[1], sublist_2[0]
# For animation purposes, the "lower" sublist will be the one with the smallest first element out of the four.
if sublist_1[0] < sublist_2[0]:
sublist_1, sublist_2 = sublist_2, sublist_1
""""
sublist_1[0] --- sublist_1[1]
/
/
<sublist_2[0]> --- sublist_2[1]
"""
if numbers[4] > sublist_1[0]:
if numbers[4] > sublist_1[1]:
sublist_1.append(numbers[4])
"""
sublist_1[0] --- sublist_1[1] --- *numbers[4]*
/
/
<sublist_2[0]> --- sublist_2[1]
"""
else:
sublist_1.insert(1, numbers[4])
"""
sublist_1[0] --- *numbers[4]* --- sublist_1[1]
/
/
<sublist_2[0]> --- sublist_2[1]
"""
else:
if numbers[4] < sublist_2[0]:
sublist_2.insert(0, numbers[4])
"""
sublist_1[0] --- sublist_1[1]
/
/
*numbers[4]* --- <sublist_2[1]> --- sublist_2[2]
"""
else:
sublist_1.insert(0, numbers[4])
"""
*numbers[4]* --- sublist_1[1] --- sublist_1[2]
/
/
<sublist_2[0]> --- sublist_2[1]
"""
if len(sublist_1) == 3:
if sublist_2[1] > sublist_1[1]:
if sublist_2[1] > sublist_1[2]:
"""
sublist_1[0] --- sublist_1[1] --- sublist_1[2] --- *sublist_2[1]*
/
/
<sublist_2[0]>
"""
return [sublist_2[0], sublist_1[0], sublist_1[1], sublist_1[2], sublist_2[1]]
else:
"""
sublist_1[0] --- sublist_1[1] --- *sublist_2[1]* --- sublist_1[2]
/
/
<sublist_2[0]>
"""
return [sublist_2[0], sublist_1[0], sublist_1[1], sublist_2[1], sublist_1[2]]
else:
if sublist_2[1] < sublist_1[0]:
"""
*sublist_2[1]* --- sublist_1[0] --- sublist_1[1] --- sublist_1[2]
/
/
<sublist_2[0]>
"""
return [sublist_2[0], sublist_2[1], sublist_1[0], sublist_1[1], sublist_1[2]]
else:
"""
sublist_1[0] --- *sublist_2[1]* --- sublist_1[1] --- sublist_1[2]
/
/
<sublist_2[0]>
"""
return [sublist_2[0], sublist_1[0], sublist_2[1], sublist_1[1], sublist_1[2]]
else:
if sublist_2[2] > sublist_1[0]:
if sublist_2[2] > sublist_1[1]:
"""
sublist_1[0] --- sublist_1[1] --- *sublist_2[2]*
/
/
<sublist_2[0]> -- sublist_2[1]
"""
return [sublist_2[0], sublist_2[1], sublist_1[0], sublist_1[1], sublist_2[2]]
else:
"""
sublist_1[0] --- *sublist_2[2]* --- sublist_1[1]
/
/
<sublist_2[0]> -- sublist_2[1]
"""
return [sublist_2[0], sublist_2[1], sublist_1[0], sublist_2[2], sublist_1[1]]
else:
if sublist_2[2] < sublist_2[1]:
"""
sublist_1[0] --- sublist_1[1]
/
/
sublist_2[0] --- *sublist_2[2]* --- sublist_2[1]
"""
return [sublist_2[0], sublist_2[2], sublist_2[1], sublist_1[0], sublist_1[1]]
else:
"""
sublist_1[0] --- sublist_1[1]
/
/
sublist_2[0] --- sublist_2[1] --- *sublist_2[2]*
"""
return [sublist_2[0], sublist_2[1], sublist_2[2], sublist_1[0], sublist_1[1]]
def test_sort_five_elements_in_seven_comparisons():
for i in range(100_000):
random_list = [random.randint(-100, 100) for _ in range(5)]
assert sort_five_elements_in_seven_comparisons(random_list) == sorted(random_list)
print("All tests passed successfully.")
test_sort_five_elements_in_seven_comparisons()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment