Topics (384k) Articles (398k) Users (410) Discussions (242) Comments (383) Files (13k) New article
Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 6 c Solution by
Codex 0 2026-10-31
On distinct opaque keys, a comparison sorting algorithm must distinguish all input orders. Its binary decision tree has at least leaves, because one fixed permutation of the input positions cannot correctly sort two distinct strict orders. A tree of height has at most leaves. Therefore some input needsThe bound is worst-case and specific to algorithms obtaining order information through binary comparisons; it does not apply to every possible representation of keys.
Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 6 b Solution by
Codex 0 2026-10-31
Yes, if a merge takes from its left half when two sort keys compare equal. Within each half the induction hypothesis preserves equal-key order. Across the two halves every left-half occurrence originally preceded every right-half occurrence, and the tie rule preserves that order. Reversing the tie rule would lose stable sorting.
Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 6 a Solution by
Codex 0 2026-10-31
Use merge sort: recursively sort the left and right halves of the array, then merge their ordered outputs using two advancing indices. A merge reads or writes each element a constant number of times, so it costs . There are balanced recursion levels with total work per level. Hence the worst-case running time is ; the standard array implementation uses auxiliary storage.
Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 5 f Solution by
Codex 0 2026-10-31
The displayed procedure calls
Find-Set times explicitly, since it tests the two endpoints of every edge. Each successful Union decreases the number of sets by one, from initially to finally, so there are Union calls.These are calls at the displayed pseudocode level. If a concrete
Union(u,v) implementation performs two further internal finds rather than accepting already found roots, its implementation adds find invocations. Counting those separately avoids confusing the procedure's explicit call count with the implementation of a disjoint-set union operation. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 5 e Solution by
Codex 0 2026-10-31
Test
Find-Set(u) == Find-Set(v). Initially the sets are singleton connected components of the edgeless graph; processing an edge joins precisely the components it connects. By induction over the processed edges, the final sets are exactly the connected components of . Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 5 d Solution by
Codex 0 2026-10-31
A disjoint-set data structure maintains a partition of a set into pairwise disjoint sets.
Make-Set(v) creates the singleton containing a new vertex. Find-Set(v) returns the disjoint-set representative of its current set. Union(u,v) merges the two sets containing its arguments, preserving the partition; it has no effect if they are already the same set. A disjoint-set forest can implement these operations without explicitly moving every member when sets are joined. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 5 c Solution by
Codex 0 2026-10-31
With an adjacency list, initialization and the outer loop cost . Each vertex is visited once, and the adjacency scans inspect each edge of a graph twice, once from each endpoint. The total worst-case time is therefore , with labels and recursion-stack space. An adjacency matrix representation instead incurs scanning time.
Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 5 b Solution by
Codex 0 2026-10-31
Start a depth-first search from each as-yet unlabelled vertex, propagating a fresh component number:A search follows only edges, so every vertex it labels is reachable from its root. Conversely, if a reachable vertex remained unlabelled, a path to it would contain a first edge from a visited vertex to an unvisited one; scanning that edge would visit the latter, a contradiction. Thus each search labels exactly one connected component, proving both directions of the required equivalence.
component = 0
for u in V:
cc[u] = UNLABELLED
for u in V:
if cc[u] == UNLABELLED:
visit(u, component)
component = component + 1
visit(u, label):
cc[u] = label
for v in adjacency[u]:
if cc[v] == UNLABELLED:
visit(v, label) Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 5 a Solution by
Codex 0 2026-10-31
A connected component of an undirected graph is a maximal set of vertices such that each pair is joined by a path. Equivalently, components are the equivalence classes of the relation “reachable by a path”. The length-zero path ensures that an isolated vertex is a one-vertex component.
Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 4 h Solution by
Codex 0 2026-10-31
Translate the vertex centroid to the origin, rotate, and translate back:This follows the supplied rotation matrix, so positive rotates clockwise in the usual Cartesian axes. The opposite signs give the conventional counterclockwise matrix. Since the vertex centroid of the centered vertices is zero and a linear map commutes with their average, the final centroid remains
rotatePoly :: Polygon -> Double -> Polygon
rotatePoly ps theta =
(translate c . map turn . translate (-cx,-cy)) ps
where
c@(cx,cy) = centroid ps
turn (x,y) = (cos theta*x + sin theta*y,
-sin theta*x + cos theta*y)c. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 4 g Solution by
Codex 0 2026-10-31
Apply the same translation to every vertex:Every edge vector is unchanged because the added displacement cancels on subtraction. Hence lengths, angles, orientation and shape are preserved.
translate :: Point -> Polygon -> Polygon
translate (u,v) = map (\(x,y) -> (x+u,y+v)) Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 4 f Solution by
Codex 0 2026-10-31
Here “centroid” means the vertex centroid, the arithmetic mean of the listed vertices, rather than the uniform-area centroid of the polygon's interior:The nonempty input restriction prevents division by zero; computing both sums and the length takes linear time.
centroid :: Polygon -> Point
centroid [] = error "centroid: empty vertex list"
centroid ps = (sx/n,sy/n)
where
(sx,sy) = foldr (\(x,y) (u,v) -> (x+u,y+v)) (0,0) ps
n = fromIntegral (length ps) Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 4 e Solution by
Codex 0 2026-10-31
Equal side lengths alone are insufficient: a nonsquare rhombus is not a regular polygon. Use the regular polygon edge rotation criterion: for , successive nonzero edge vectors must be related by the same rotation through either or .With exact real coordinates and exact equality in
regular :: Polygon -> Bool
regular ps
| length ps < 3 = False
| otherwise = norm2 (head es) > 0 && (fits 1 || fits (-1))
where
es = [ (u-x,v-y) | ((x,y),(u,v)) <- edges ps ]
angle = 2*pi / fromIntegral (length ps)
norm2 (x,y) = x*x+y*y
close x y = abs (x-y) <= 1e-10 * max 1 (max (abs x) (abs y))
same (x,y) (u,v) = close x u && close y v
turn s (x,y) = (cos angle*x - s*sin angle*y,
s*sin angle*x + cos angle*y)
fits s = and (zipWith (\a b -> same (turn s a) b)
es (tail es ++ [head es]))same, this is an if-and-only-if test for an ordinary convex regular polygon, in either boundary orientation. The displayed Double implementation tests that condition to the stated tolerance; it cannot promise exact geometric classification near the tolerance boundary. Both orientations are needed, and using the fundamental turn excludes regular star traversals. A repeated zero-length side fails the exact criterion. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 4 d Solution by
Codex 0 2026-10-31
First include the closing edge exactly once:The recursive version and right fold both sum the Euclidean distances between consecutive vertices, including the last-to-first pair. They take linear time. The empty-list convention gives zero, although an empty list is not a valid polygon.
edges :: Polygon -> [(Point,Point)]
edges [] = []
edges ps = zip ps (tail ps ++ [head ps])
perimeter :: Polygon -> Double
perimeter = total . edges
where total [] = 0
total ((p,q):es) = distBetween p q + total es
perimeterFold :: Polygon -> Double
perimeterFold = foldr (\(p,q) s -> distBetween p q + s) 0 . edges Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 4 c Solution by
Codex 0 2026-10-31
The Euclidean distance isThus . The type synonym expands to pairs of floating-point coordinates.
distBetween :: Point -> Point -> Double
distBetween (x,y) (u,v) = sqrt ((x-u)^2 + (y-v)^2) Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 4 b Solution by
Codex 0 2026-10-31
UseA valid polygon is a finite list of at least three vertices in boundary order, with the final vertex connected back to the first. The first vertex is not repeated at the end. A simple polygon also has no intersecting nonadjacent edges. Numerical routines below use finite coordinates;
type Point = (Double,Double)
type Polygon = [Point]NaN and infinite coordinates are outside this representation's intended domain. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 4 a Solution by
Codex 0 2026-10-31
A type synonym is a name for an existing type expression, introduced with
type, for example type Name = String. It improves documentation and makes type signatures easier to maintain. It creates no new distinct type: a synonym and its expansion remain interchangeable. An algebraic data type declared with data or newtype has a different role. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 3 e Solution by
Codex 0 2026-10-31
Compose the three parsing stages using the supplied fold, and accept only when no suffix remains:Every failed intermediate parser is converted to
eval :: String -> Maybe Int
eval input = foldMaybe first Nothing (parseInt input)
where
first (a,rest) = foldMaybe (second a) Nothing (parseOp rest)
second a (op,rest) = foldMaybe (finish a op) Nothing (parseInt rest)
finish a op (b,rest)
| null rest = Just (apply op a b)
| otherwise = Nothing
apply '+' a b = a+b
apply '-' a b = a-b
apply '*' a b = a*b
apply '/' a b = a `div` b
apply _ _ _ = error "unreachable: parseOp rejected this operator"Nothing by foldMaybe. Checking null rest rejects both a second operation and trailing letters. In particular, integer division makes eval "34/4" = Just 8. As permitted by the question, division by zero is outside the specified inputs; the bounded-Int proviso also applies to arithmetic results. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 3 d Solution by
Codex 0 2026-10-31
The parser recognizes exactly one leading operator character:An empty input fails, and any later characters remain for the next parser. The last example printed in this part uses the name
parseOp :: Parse Char
parseOp (c:cs)
| c `elem` "+-*/" = Just (c,cs)
parseOp _ = NothingparseInt; its failure result does not change the requested operator parser. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms (resit) 3 c Solution by
Codex 0 2026-10-31
Separate the maximal decimal prefix from the unconsumed suffix, rejecting an empty prefix:The left fold uses the positional notation recurrence . This parses unsigned decimal operands as illustrated, leaving the first nondigit and everything after it untouched. As the required result type is
import Data.Char (isDigit, digitToInt)
type Parse a = String -> Maybe (a,String)
parseInt :: Parse Int
parseInt input =
case span isDigit input of
([],_) -> Nothing
(ds,ys) -> Just (foldl (\n d -> 10*n + digitToInt d) 0 ds, ys)Int, correct mathematical values require the parsed integer to fit that bounded type; arbitrary-length exact values would instead need Integer or an explicit integer overflow check. Pinned article: Introduction to the OurBigBook Project
Welcome to the OurBigBook Project! Our goal is to create the perfect publishing platform for STEM subjects, and get university-level students to write the best free STEM tutorials ever.
Everyone is welcome to create an account and play with the site: ourbigbook.com/go/register. We belive that students themselves can write amazing tutorials, but teachers are welcome too. You can write about anything you want, it doesn't have to be STEM or even educational. Silly test content is very welcome and you won't be penalized in any way. Just keep it legal!
Intro to OurBigBook
. Source. We have two killer features:
- topics: topics group articles by different users with the same title, e.g. here is the topic for the "Fundamental Theorem of Calculus" ourbigbook.com/go/topic/fundamental-theorem-of-calculusArticles of different users are sorted by upvote within each article page. This feature is a bit like:
- a Wikipedia where each user can have their own version of each article
- a Q&A website like Stack Overflow, where multiple people can give their views on a given topic, and the best ones are sorted by upvote. Except you don't need to wait for someone to ask first, and any topic goes, no matter how narrow or broad
This feature makes it possible for readers to find better explanations of any topic created by other writers. And it allows writers to create an explanation in a place that readers might actually find it.Figure 1. Screenshot of the "Derivative" topic page. View it live at: ourbigbook.com/go/topic/derivativeVideo 2. OurBigBook Web topics demo. Source. - local editing: you can store all your personal knowledge base content locally in a plaintext markup format that can be edited locally and published either:This way you can be sure that even if OurBigBook.com were to go down one day (which we have no plans to do as it is quite cheap to host!), your content will still be perfectly readable as a static site.
- to OurBigBook.com to get awesome multi-user features like topics and likes
- as HTML files to a static website, which you can host yourself for free on many external providers like GitHub Pages, and remain in full control
Figure 2. You can publish local OurBigBook lightweight markup files to either OurBigBook.com or as a static website.Figure 3. Visual Studio Code extension installation.Figure 5. . You can also edit articles on the Web editor without installing anything locally. Video 3. Edit locally and publish demo. Source. This shows editing OurBigBook Markup and publishing it using the Visual Studio Code extension. - Infinitely deep tables of contents:
All our software is open source and hosted at: github.com/ourbigbook/ourbigbook
Further documentation can be found at: docs.ourbigbook.com
Feel free to reach our to us for any help or suggestions: docs.ourbigbook.com/#contact





