Skip to content
Open
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
89 changes: 66 additions & 23 deletions sorts/pancake_sort.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,82 @@
"""
This is a pure Python implementation of the pancake sort algorithm
"""Pancake Sort Algorithm Implementation.

This module provides a pure Python implementation of the Pancake Sort algorithm.
Pancake sort is a sorting algorithm that sorts an array by repeatedly flipping
subsections of the array, similar to how you might sort a stack of pancakes
by inserting a spatula and flipping the top portion.

The algorithm works by finding the maximum element, flipping it to the top,
then flipping it down to its correct position. This process is repeated for
the remaining unsorted portion.

Time Complexity: O(n^2) - We perform n iterations, each with up to 2 flips
Space Complexity: O(1) - In-place sorting, only uses a constant amount of extra space

For doctests run following command:
python3 -m doctest -v pancake_sort.py
python3 -m doctest -v pancake_sort.py
or
python -m doctest -v pancake_sort.py
python -m doctest -v pancake_sort.py
For manual testing run:
python pancake_sort.py
python pancake_sort.py
"""

from typing import Any


def pancake_sort(arr: list[Any]) -> list[Any]:
"""Sort an array using the Pancake Sort algorithm.

Pancake sort works by finding the maximum unsorted element, flipping it to
the top of the array, then flipping the entire unsorted portion to move the
maximum to its correct position at the end.

Args:
arr: A list of comparable items to be sorted.

Returns:
The input list sorted in ascending order.

Time Complexity:
O(n^2) where n is the length of the array.
- We iterate n times (once for each position)
- Each iteration involves finding max O(n) and up to 2 flips O(n)

Space Complexity:
O(1) - sorting is done in-place with only constant extra space.

def pancake_sort(arr):
"""Sort Array with Pancake Sort.
:param arr: Collection containing comparable items
:return: Collection ordered in ascending order of items
Examples:
>>> pancake_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> pancake_sort([])
[]
>>> pancake_sort([-2, -5, -45])
[-45, -5, -2]
>>> pancake_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> pancake_sort([])
[]
>>> pancake_sort([-2, -5, -45])
[-45, -5, -2]
>>> pancake_sort([1])
[1]
>>> pancake_sort([3, 1, 4, 1, 5, 9, 2, 6])
[1, 1, 2, 3, 4, 5, 6, 9]
"""
cur = len(arr)
while cur > 1:
# Find the maximum number in arr
mi = arr.index(max(arr[0:cur]))
# Reverse from 0 to mi
arr = arr[mi::-1] + arr[mi + 1 : len(arr)]
# Reverse whole list
arr = arr[cur - 1 :: -1] + arr[cur : len(arr)]
# Find the index of maximum element in arr[0:cur]
max_index = arr.index(max(arr[:cur]))

# Move maximum element to end of current unsorted portion:
# 1. Flip to bring max to the beginning
arr[: max_index + 1] = reversed(arr[: max_index + 1])
# 2. Flip to send max to position cur-1
arr[:cur] = reversed(arr[:cur])

cur -= 1
return arr


if __name__ == "__main__":
user_input = input("Enter numbers separated by a comma:\n").strip()
import doctest

doctest.testmod()

user_input = input("Enter numbers separated by comma: ").strip()
unsorted = [int(item) for item in user_input.split(",")]
print(pancake_sort(unsorted))
print(f"Unsorted: {unsorted}")
print(f"Sorted: {pancake_sort(unsorted)}")