From eb62b1433f300474b8f224bafd4a2f7c4d51da50 Mon Sep 17 00:00:00 2001 From: Rokeshwaran Date: Sun, 13 Sep 2026 12:40:37 +0530 Subject: [PATCH] sorts: make pancake_sort generic over Comparable items Part of #15234 - switch pancake_sort's TypeVar to the Comparable/TypeVar-bound pattern used by insertion_sort.py - add doctests covering strings, floats, and random data - register pancake_sort in tests/test_sorts.py's shared battery and the non-comparable-items rejection test --- sorts/pancake_sort.py | 34 +++++++++++++++++++++++++++++----- tests/test_sorts.py | 3 +++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/sorts/pancake_sort.py b/sorts/pancake_sort.py index 7fa4c02e981f..09c604f8c81f 100644 --- a/sorts/pancake_sort.py +++ b/sorts/pancake_sort.py @@ -1,5 +1,6 @@ """ This is a pure Python implementation of the pancake sort algorithm + For doctests run following command: python3 -m doctest -v pancake_sort.py or @@ -9,15 +10,23 @@ """ from collections.abc import Sequence -from typing import TypeVar +from typing import Any, Protocol, TypeVar + + +class Comparable(Protocol): + def __lt__(self, other: Any, /) -> bool: ... + -T = TypeVar("T") +T = TypeVar("T", bound=Comparable) -def pancake_sort[T](arr: Sequence[T]) -> list[T]: +def pancake_sort[T: Comparable](arr: Sequence[T]) -> list[T]: """Sort Array with Pancake Sort. - :param arr: Collection containing comparable items - :return: Collection ordered in ascending order of items + + :param arr: some ordered collection with heterogeneous comparable items + inside + :return: the same collection ordered by ascending + Examples: >>> pancake_sort([0, 5, 3, 2, 2]) [0, 2, 2, 3, 5] @@ -25,7 +34,18 @@ def pancake_sort[T](arr: Sequence[T]) -> list[T]: [] >>> pancake_sort([-2, -5, -45]) [-45, -5, -2] + >>> pancake_sort(['d', 'a', 'b', 'e', 'c']) == sorted(['d', 'a', 'b', 'e', 'c']) + True + >>> import random + >>> collection = random.sample(range(-50, 50), 100) + >>> pancake_sort(collection) == sorted(collection) + True + >>> import string + >>> collection = random.choices(string.ascii_letters + string.digits, k=100) + >>> pancake_sort(collection) == sorted(collection) + True """ + arr = list(arr) cur = len(arr) while cur > 1: # Find the maximum number in arr @@ -39,6 +59,10 @@ def pancake_sort[T](arr: Sequence[T]) -> list[T]: if __name__ == "__main__": + from doctest import testmod + + testmod() + user_input = input("Enter numbers separated by a comma:\n").strip() unsorted = [int(item) for item in user_input.split(",")] print(pancake_sort(unsorted)) diff --git a/tests/test_sorts.py b/tests/test_sorts.py index 2c9b79aa4bfe..2ac928737e78 100644 --- a/tests/test_sorts.py +++ b/tests/test_sorts.py @@ -33,6 +33,7 @@ from sorts.iterative_merge_sort import iter_merge_sort from sorts.merge_sort import merge_sort from sorts.odd_even_sort import odd_even_sort +from sorts.pancake_sort import pancake_sort from sorts.patience_sort import patience_sort from sorts.quick_sort import quick_sort from sorts.selection_sort import selection_sort @@ -64,6 +65,7 @@ def test_heap_sort() -> None: iter_merge_sort, merge_sort, odd_even_sort, + pancake_sort, patience_sort, quick_sort, selection_sort, @@ -121,6 +123,7 @@ def test_sort_matches_builtin(sort, case) -> None: gnome_sort, insertion_sort, merge_sort, + pancake_sort, selection_sort, ], ids=lambda f: f.__name__,