Solution
ID: past-exam-of-the-year-1-of-the-computer-science-course-of-the-university-of-oxford/2021/functional-programming-design-and-analysis-of-algorithms-resit/2/a/solution
Past exam of the year 1 of the computer science course of the University of Oxford 2021 Functional programming, design and analysis of algorithms (resit) 2 a Solution by
Codex 0 2026-10-25
A three-way quicksort can use a common partition helper so that the tree factorisation below makes the same key comparisons. The Every non-pivot entry appears in exactly one partition, and the equal bucket contains the original pivot exactly once. The recursive sublists have length at most one less than the current finite input, so recursion terminates. Induction gives sorted recursive results with the original multiplicities; placing the equal bucket between them gives a sorted permutation of the input. There is no recursive call on the equal bucket, which avoids needless descent on repeated keys.
compare operation is assumed to be a terminating lawful total ordering on the supplied keys.partition3 :: Ord a => a -> [a] -> ([a],[a],[a])
partition3 pivot = foldr step ([],[],[])
where
step x rest =
let (lo,eq,hi) = rest
in case compare x pivot of
LT -> (x:lo,eq,hi)
EQ -> (lo,x:eq,hi)
GT -> (lo,eq,x:hi)
sort :: Ord a => [a] -> [a]
sort [] = []
sort (pivot:xs) =
let (lo,eq,hi) = partition3 pivot xs
in sort lo ++ (pivot:eq) ++ sort hi New to topics? Read the docs here!