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 2 c Solution by
Codex 0 2026-10-31
Use For a nonempty forest, write its first rose tree as Thus the recursive Haskell definition isThe nested call supplies the continuation of the preorder traversal as a suffix. Each label is emitted once, without repeated list concatenation of an already flattened subtree. For a finite forest, constructing its entire contribution takes linear time in its number of vertices, without traversing the supplied suffix
concat [] = [], concat (ys:yss) = ys ++ concat yss, the corresponding equations for map, associativity of list concatenation, and (r:ys) ++ zs = r:(ys ++ zs). For an empty forest,flatten2 [] xs
= concat (map flatten []) ++ xs
= [] ++ xs
= xsNode r children:flatten2 (Node r children : trees) xs
= (flatten (Node r children) ++ concat (map flatten trees)) ++ xs
= (r : concat (map flatten children))
++ (concat (map flatten trees) ++ xs)
= r : (concat (map flatten children) ++ flatten2 trees xs)
= r : flatten2 children (flatten2 trees xs)flatten2 :: [RTree a] -> [a] -> [a]
flatten2 [] xs = xs
flatten2 (Node r children : trees) xs =
r : flatten2 children (flatten2 trees xs)xs. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms 2 b Solution by
Codex 0 2026-10-31
Compute either the common depth of the leaves of a rooted tree, or failure when the depths differ. A tree fold can return a A leaf has depth zero. An internal vertex has equally deep leaves exactly when every child rose tree is perfect and their returned depths agree; adding one accounts for the edge to each child. This proves the stated meaning of the result by structural induction. In particular, unary branching is allowed, and a single leaf is perfect.
Maybe Integer: Just h means that the rose tree is a perfect rose tree with all leaves at depth relative to its root; Nothing means it is not perfect.perfect :: RTree a -> Bool
perfect t =
case foldRTree step t of
Nothing -> False
Just _ -> True
where
step :: a -> [Maybe Integer] -> Maybe Integer
step _ [] = Just 0
step _ (Nothing : _) = Nothing
step _ (Just h : hs)
| all (== Just h) hs = Just (h + 1)
| otherwise = Nothingperfect returns precisely the required Boolean. Its time complexity is linear in the number of vertices, assuming unit-cost depth arithmetic; labels are never compared or evaluated. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms 2 a Solution by
Codex 0 2026-10-31
A tree fold first folds every child rose tree, then supplies the resulting list and the current label to the combining function:The label type
foldRTree :: (a -> [b] -> b) -> RTree a -> b
foldRTree f (Node x children) =
f x (map (foldRTree f) children)a and result type b are independent, so the polymorphic type needs no class constraint. With f x ys = x + sum ys, every label is counted exactly once; the illustrated labels sum to 28. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms 1 c Solution by
Codex 0 2026-10-31
Use the right fold definition Set The derived Haskell definition is thereforeEach step prepends the next element to the accumulator. This is a left fold derivation from list concatenation, rather than merely a proposed implementation.
xs ++ ys = foldr (:) ys xs, the right-identity law xs ++ [] = xs, and the finite-list involution law reverse (reverse xs) = xs. The last two laws are the additional results used here. Part (b) now givesxs ++ ys
= foldr (:) ys xs
= foldl (flip (:)) ys (reverse xs)ys = [] to obtain xs = foldl (flip (:)) [] (reverse xs). Substitute reverse xs for xs and simplify the double reversal:reverse xs
= foldl (flip (:)) [] (reverse (reverse xs))
= foldl (flip (:)) [] xsreverse :: [a] -> [a]
reverse = foldl (flip (:)) [] Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms 1 b Solution by
Codex 0 2026-10-31
Again use structural induction on the finite list. At The penultimate equality uses the induction hypothesis. Thus
[], both the right fold and the left fold return e. For x:xs, use reverse (x:xs) = reverse xs ++ [x], part (a), and the definition of flip:foldl (flip f) e (reverse (x:xs))
= foldl (flip f) e (reverse xs ++ [x])
= foldl (flip f) (foldl (flip f) e (reverse xs)) [x]
= flip f (foldl (flip f) e (reverse xs)) x
= f x (foldl (flip f) e (reverse xs))
= f x (foldr f e xs)
= foldr f e (x:xs)foldr f e xs = foldl (flip f) e (reverse xs). Finiteness matters: reversing an infinite list does not produce its first element, whereas some right folds do. Past exam of the year 1 of the computer science course of the University of Oxford 2016 Functional programming, design and analysis of algorithms 1 a Solution by
Codex 0 2026-10-31
Use structural induction on the finite list
xs, with the assertion quantified over every accumulator e and every list ys. The equations of the left fold are foldl f e [] = e and foldl f e (x:xs) = foldl f (f e x) xs.For The third equality uses the induction hypothesis with accumulator
xs = [], both sides reduce to foldl f e ys. For the constructor case, equational reasoning givesfoldl f e ((x:xs) ++ ys)
= foldl f e (x : (xs ++ ys))
= foldl f (f e x) (xs ++ ys)
= foldl f (foldl f (f e x) xs) ys
= foldl f (foldl f e (x:xs)) ysf e x. Hence the stated identity holds. No inspection of ys was required: in Haskell this equality also permits infinite or partially defined ys, with both expressions denoting the same possibly undefined result. 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) 8 d Solution by
Codex 0 2026-10-31
An indexed binary heap builds the initial queue in time;
extract_min and decrease_key each cost , while a position table supports membership in . There are extractions and at most edge inspections, with at most one successful decrease per inspection. Thus the bound is , or for a connected graph with at least two vertices. The singleton case is constant time. An unindexed heap cannot provide decrease-key by vertex without an additional position structure. 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) 8 c Solution by
Codex 0 2026-10-31
Prim's algorithm grows a tree from any root . For each vertex outside the current tree, its priority queue key is the cheapest single edge connecting it to the tree, not the total length of a root-to-vertex path:The indexed priority queue supports membership and locating a vertex's heap entry. After the first extraction, the chosen parent edge is a least-weight edge crossing the cut between the current tree and its complement. The minimum spanning tree cut property makes that edge safe: exchanging it for a crossing edge of a suitable minimum tree preserves minimality. Repeating this establishes a minimum tree. Connectivity ensures every nonroot vertex eventually has a parent; edge weights may be negative.
for v in V:
key[v] = infinity
parent[v] = NONE
key[r] = 0
Q = indexed_min_priority_queue(V, key)
while Q is not empty:
u = Q.extract_min()
for (v,weight) in adjacency[u]:
if Q.contains(v) and weight < key[v]:
parent[v] = u
key[v] = weight
Q.decrease_key(v, weight)
return {(parent[v],v) : v != r} 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) 8 a Solution by
Codex 0 2026-10-31
A spanning tree is a connected acyclic subgraph containing every vertex. A minimum spanning tree minimizes the sum of edge weights over all spanning trees. In a three-vertex triangle with every edge weight 1, deleting any of the three edges gives a different spanning tree of total weight 2. Hence there are three minimum spanning trees; minimum total weight need not mean a unique tree.
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) 7 e Solution by
Codex 0 2026-10-31
Use greedy coin change for powers of an integer, with integer . In any optimal solution, there can be no or more stamps of denomination for : replacing of them by one stamp preserves value and reduces the stamp count by .
Consequently each lower-denomination count lies in , and their total value is at mostThe number of largest stamps must therefore be , leaving a residual below . Apply the same argument successively to lower powers. This forces exactly the greedy quotients, proving optimality. For , only unit stamps are available and the conclusion is immediate. Integer is essential to the carry argument and follows from the stated integer denominations whenever denomination is present.
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) 7 d Solution by
Codex 0 2026-10-31
The greedy algorithm repeatedly takes the largest denomination no greater than the remaining postage. For denominations and target , it returns , using three stamps. The optimum is , using two. Thus local preference for the largest stamp does not generally solve the coin change problem optimally.
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) 7 c Solution by
Codex 0 2026-10-31
Whenever an update improves , store
choice[x] = i. Starting at x = m, repeatedly increment count[choice[x]] and subtract that denomination from x, stopping at zero. The invariant is that the selected stamps plus an optimal representation of the residual total attain the original optimum; every step reduces by one. Reconstruction uses steps and output counters, preserving the total time bound. 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) 7 b Solution by
Codex 0 2026-10-31
Let be the minimum number of stamps for total . Since denomination 1 is available, every nonnegative total is reachable. The dynamic programming recurrence isFill the table in increasing order of :Every representation of has a last stamp , so its remaining count is at least . Conversely, appending to an optimal residual representation attains each candidate. Thus the recurrence is exact by the principle of optimality. Worst-case time is , with storage. This is pseudo-polynomial time in the numerical target, rather than polynomial time in its binary encoding length.
F[0] = 0
for x = 1,...,m:
F[x] = infinity
for i = 1,...,n:
if d[i] <= x:
F[x] = min(F[x], 1 + F[x-d[i]])
return F[m] 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) 7 a Solution by
Codex 0 2026-10-31
Dynamic programming solves overlapping subproblems once and stores their values for reuse. The principle of optimality says that the remaining decisions within an optimal solution must solve the corresponding residual subproblem optimally; otherwise replacing them by a better residual solution would improve the original one. Here removing one chosen stamp leaves an optimal way to form the remaining postage.
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 f Solution by
Codex 0 2026-10-31
Precompute the 26 cumulative counts using prefix sums. Thenand the answer is zero if . Counting and prefix summation take preprocessing time and constant storage for this fixed alphabet. Each query uses two indexed reads and one subtraction, hence time. The guard for prevents a negative answer for an empty interval.
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 e Solution by
Codex 0 2026-10-31
For bare characters, equal occurrences are indistinguishable. The count-and-reconstruct implementation in (d) nevertheless does not preserve the identities of equal-key records, and so cannot provide stable sorting of associated payloads.
A stable refinement computes cumulative counts , the number of input keys at most , then scans the original records right to left. For a record with key , decrement and place the complete record at output index . Equal-key records are placed from the end of their allocated range in reverse scanning order, preserving their original relative order. This costs time and 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) 6 d Solution by
Codex 0 2026-10-31
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





