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 2018 Functional programming, design and analysis of algorithms 6 a Solution by
Codex 0 Created 2026-10-31 Updated 2026-11-05
There are three useful distinctions between dynamic programming and a conventional divide-and-conquer algorithm.
- A divide-and-conquer algorithm typically splits one instance into mostly separate smaller instances; dynamic programming deliberately recognizes overlapping subproblems that recur along different decision histories.
- A dynamic programming state is solved once and its result reused through a table or memoization. A direct divide-and-conquer algorithm normally combines the results of its recursive children without retaining a table indexed by all repeated states.
- The dependency structure of a direct recursive decomposition is a recursion tree; dynamic programming evaluates a directed acyclic graph of states in dependency order, either bottom-up or by memoization. Its cost is the number of distinct states times the work per state, rather than the number of occurrences in the expanded recursion tree.
These are paradigm-level distinctions, not mutually exclusive definitions: a recursive algorithm can use memoization, and dynamic programming need not be implemented iteratively. For optimization, the dynamic programming state and optimal substructure justify combining stored optimum values; storing repeated work alone does not prove the state is sufficient.
Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 5 c Solution by
Codex 0 2026-10-31
Sort records
(value,original_index) by value using merge sort. For each record with value , run binary search for value among the sorted records; return the two retained original indices at the first match, otherwise return nil after all records.If a valid pair exists, its smaller entry is inspected and the matching doubled entry is found by binary search. Conversely every returned pair satisfies the requested equality. Positivity gives , so the returned entries are distinct even if other entries repeat. Sorting costs , and at most binary searches cost altogether. Total time is , using the paper's unit-cost arithmetic model; doubling large machine integers would require overflow-safe arithmetic.
Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 5 b Solution by
Codex 0 2026-10-31
On a worst-case branch, the described sequential quarter-point tests make three equality tests per reduction, giving until constant size. Thus . Ordinary binary search makes one equality test per halving: , so .
Both searches take time, but the specified quaternary search uses asymptotically as many equality tests. A quarter-sized branch does not compensate for the three sequential pivots. The numerical ratio concerns precisely the unit equality-test model in the paper; counting ordering comparisons, array accesses or a differently arranged pivot decision tree requires its own constants.
Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 5 a Solution by
Codex 0 2026-10-31
Merge sort splits the array into two halves, recursively sorts both and merges their sorted outputs. During the merge algorithm, compare the first unconsumed entry of each half, emit the smaller and advance that half; append the remainder when one half ends. The emitted prefix is always sorted and contains exactly the already consumed entries, proving the merge step correct. Induction on input length proves the full sorting algorithm correct.
The recurrence relation is for powers of two, with constant base cost. In the Master theorem, and , matching the merge term. Hence . Floor/ceiling splits give the same bound for arbitrary ; conventional merging uses auxiliary space.
Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 4 d Solution by
Codex 0 2026-10-31
type Weight = (Int,Int,Int)
weight :: Results -> Weight
weight (Results _ scores) =
(sum (map points scores),
sum [gf - ga | (gf,ga) <- scores],
sum (map fst scores))
where
points (gf,ga)
| gf > ga = 3
| gf == ga = 1
| otherwise = 0The components are total points, total goal difference and total goals scored. The Haskell Ord class compares tuples in lexicographic order, so a greater first component dominates all later components; only ties reach the next criterion. Exactly equal triples remain tied because no further ranking criterion was specified. In the supplied fixture data the descending triples are , , , , , and , respectively for United, Athletic, City, Albion, Rovers, Corinthians and Thistle.
Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 4 c Solution by
Codex 0 2026-10-31
Choose each team once using
teams, then scan every match with that team as the reference perspective:data Results = Results Team [(Int,Int)]
extract :: [[Match]] -> [Results]
extract days = [Results t (scores t) | t <- teams days]
where
games = concat days
scores t = concatMap (contribution t) games
contribution t (Match a ga b gb)
| t == a = [(ga,gb)]
| t == b = [(gb,ga)]
| otherwise = []In a valid match the teams are distinct. The first guard records the first team's goals-for and goals-against; the second reverses that perspective for the opponent. The common
games binding preserves day/match order, although the result does not need a chronological ordering condition. Each team receives exactly one record because teams has no duplicates. The algorithm makes one scan per team; it deliberately prioritizes a transparent functional programming definition over an unrequested performance improvement. Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 4 b Solution by
Codex 0 2026-10-31
teams :: [[Match]] -> [Team]
teams days = unique [t | Match a _ b _ <- concat days, t <- [a,b]]
where
unique [] = []
unique (t:ts) = t : unique (filter (/= t) ts)Every emitted name belongs to some match, and every participating team enters the intermediate list. At each recursive step,
unique emits its first remaining name once and deletes precisely its later occurrences. Induction therefore proves both coverage and absence of duplicates. The output preserves first appearance; no particular team ordering was required. This simple list implementation can take quadratic time in the number of participant occurrences, which is permissible here; the question imposes no efficiency target. Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 4 a Solution by
Codex 0 2026-10-31
Use a type synonym for names and an algebraic data type with the two teams and their goals in the given positional order:
type Team = String
data Match = Match Team Int Team IntTeam is a synonym, not a new runtime wrapper. Match on the left is the type constructor, while the same spelling on the right is a data constructor in a different namespace. Its value-level type signature is Match :: Team -> Int -> Team -> Int -> Match. Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 3 h Solution by
Codex 0 2026-10-31
Compose the three functions:
reverse :: [a] -> [a]
reverse = abs . rev . rep Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 3 g Solution by
Codex 0 2026-10-31
rev :: CatList a -> CatList a
rev Nil = Nil
rev (One x) = One x
rev (Cat l r) = Cat (rev r) (rev l)The proof uses and structural induction. The complete representation is processed and reconstructed in time. This is worst-case optimal for fully processing arbitrary explicit input representations with constructors; the datatype allows output information to be hidden at any leaf. Lazy evaluation can expose only an initial part of a result sooner, and this statement does not assert that every partial observation costs .
Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 3 f Solution by
Codex 0 2026-10-31
A concatenation tree may contain arbitrarily many
Cat and Nil nodes while denoting an empty or singleton list. For example, repeatedly wrap One x as Cat Nil previous. The output length stays one while the input size grows without bound. An arbitrary leaf could hide another One, so a correct general conversion cannot disregard unexamined branches. Output length alone therefore cannot bound the work; input size must be included. Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 3 e Solution by
Codex 0 2026-10-31
Carry the eventual output tail as an accumulator, thereby avoiding repeated list concatenation:
abs :: CatList a -> [a]
abs t = flatten t []
where
flatten Nil zs = zs
flatten (One x) zs = x : zs
flatten (Cat l r) zs = flatten l (flatten r zs)The invariant is
flatten t zs = denotation t ++ zs. It is immediate for Nil and One; at Cat, applying the two induction hypotheses and associativity of list concatenation proves it. In particular, the empty accumulator gives the required abstraction.Each concatenation tree constructor is processed once, and each
One emits one result cons. Consequently full production takes time, where is the input constructor count, on every tree shape. This is a difference list calculation written with an explicit tail, an instance of linear flattening of a binary tree. The call stack can have depth for a badly skewed input; a linear time bound does not imply logarithmic stack space. Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 3 d Solution by
Codex 0 2026-10-31
One simple right-associated representation is
rep :: [a] -> CatList a
rep [] = Nil
rep (x:xs) = Cat (One x) (rep xs)It constructs two data constructors per input element and one final
Nil, so full construction takes time and produces constructors. Structural induction shows that its denotation is the original list. Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 3 c Solution by
Codex 0 2026-10-31
Three distinct concatenation tree representations of the empty list are
Nil, Cat Nil Nil, and Cat (Cat Nil Nil) Nil. For the singleton [x], use One x, Cat Nil (One x), and Cat (One x) Nil.An empty branch changes the data structure without changing its denoted list. Repeating this padding gives arbitrarily many representations of the same list; there is no uniqueness invariant in the stated datatype.
Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 3 b Solution by
Codex 0 2026-10-31
For input length , the successive list concatenations copy prefixes of lengths . Thus and . The direct implementation takes time for a fully produced nonempty reversal. The repeated copying, rather than the number of recursive calls alone, causes the quadratic cost.
Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 3 a Solution by
Codex 0 2026-10-31
(++) :: [a] -> [a] -> [a]
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)For finite first-operand length , fully producing the copied spine costs , independently of the second-operand length. With lazy evaluation, requesting only the first few result constructors can cost less; the bound concerns the complete concatenation spine, without forcing its element values or traversing the already existing second operand.
Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 2 h Solution by
Codex 0 2026-10-31
The derivative relations and initial values give , , and . Integrating from zero yields and . Thus use mutually recursive lazy lists:
sinx, cosx :: Fractional a => [a]
sinx = integral cosx
cosx = minus one (integral sinx)Both heads are available immediately, and later coefficients depend on earlier coefficients of the other stream. The resulting formal power series are and . Their zero coefficients and alternating signs follow directly from the coupled recurrence relations, providing a coefficientwise proof without assumptions about analytic convergence.
Past exam of the year 1 of the computer science course of the University of Oxford 2018 Functional programming, design and analysis of algorithms 2 g Solution by
Codex 0 2026-10-31
The derivative fixed-point equation is unsuitable as an executable definition: requesting its first coefficient asks for the second coefficient of the same stream, then the third, indefinitely. It is not productive. As an algebraic equation it is also missing the constant coefficient: every scalar multiple of the formal power series exponential, including zero, satisfies it.
expx :: Fractional a => [a]
expx = plus one (integral expx)The initial coefficient is available as
1 + 0; each subsequent coefficient needs only a previously determined coefficient. The recurrence relation is and , so . This proves both uniqueness of the formal solution and productivity of every finite coefficient list prefix. 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





