py_cryptic_sorter — Multi-Criteria String Sort
Difficulty: hard
Sort a list of strings according to the following criteria, in order:
- Primary: by string length (shortest first).
- Secondary: ASCII order, except letters are compared case-insensitively (for strings of the same length).
- Tertiary: by number of vowels, ascending (for same length and lexically equal under rule 2).
- Equal strings keep their original input order.
def cryptic_sorter(strings: list[str]) -> list[str]:
Examples
>>> cryptic_sorter(["apple", "cat", "banana", "dog", "elephant"])
["cat", "dog", "apple", "banana", "elephant"]
>>> cryptic_sorter(["aaa", "bbb", "AAA", "BBB"])
["aaa", "AAA", "bbb", "BBB"]
>>> cryptic_sorter(["hello", "world", "hi", "test"])
["hi", "test", "hello", "world"]
>>> cryptic_sorter([])
[]
>>> cryptic_sorter([""])
[""]
Solution
Download py_cryptic_sorter.pydef cryptic_sorter(strings: list[str]) -> list[str]:
vowels = set("aeiouAEIOU")
def key(s: str):
return (len(s), s.lower(), sum(1 for c in s if c in vowels))
return sorted(strings, key=key)
How It Works
Goal: Order strings by a composite key with a strict precedence — length, then case-insensitive lex order, then vowel count.
Approach: Build a tuple key (length, lowercased, vowel_count). Python compares tuples lexicographically, so the first differing component decides — which is exactly the precedence the spec asks for. sorted is stable, so the rule-4 requirement (preserve input order for full ties) is satisfied for free.
Step by step:
- Define a
key(s)returning(len(s), s.lower(), vowel_count). s.lower()produces the case-insensitive secondary key — its tuple comparison falls through to it only when lengths tie.- Vowel count breaks the next tie when the lowercased forms are also equal (
"aaa"vs"AAA"). - Stable sort preserves the original order for fully equal keys.
Key concept: Tuple keys for multi-level sorting — Python's tuple comparison is exactly the lexicographic order you'd hand-code, so the cleanest way to express "sort by A, then B, then C" is to return (A, B, C) from the key.