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 2013 Digital systems, linear algebra, introduction to formal proof 2 b Solution by
Codex 0 2026-10-31
The opcode occupies bits , the arithmetic logic unit operation is wired directly to , and an immediate operand uses all of . A three-register instruction needs fifteen register-selection bits, whereas an immediate instruction must retain independent source and destination selectors outside .
Thus put and in the ten bits , and place in five of , where it can overlap the unused immediate operand of a register instruction. One valid instruction encoding isBits are unused for a three-register instruction. In an immediate instruction, has no effect because its read value is deselected by the
ToAlu multiplexer. In a store, selects the address and selects the data; must be zero to suppress the incidental register write. These observations follow the original datapath, particularly its direct memory-address connection and the connection from the ToAlu output to memory write data.[ref]Digital systems, linear algebra, introduction to formal proof examination paper by the University of Oxford (2013). Printed p. 3, processor block diagram
Past exam of the year 1 of the computer science course of the University of Oxford 2013 Digital systems, linear algebra, introduction to formal proof 2 a Solution by
Codex 0 2026-10-31
Use the MIPS zero register as a write-suppression destination: encode . There are only 31 stored processor registers, and address zero denotes the constant-zero source rather than a writable storage cell. Its writes are discarded, soThis permits a
store to write memory while its unavoidable register file write has no effect. It also implements a no-operation by selecting no memory write and destination zero. The statement that reads of register zero return zero is realized consistently by this standard constant-zero, discard-writes implementation. Past exam of the year 1 of the computer science course of the University of Oxford 2013 Digital systems, linear algebra, introduction to formal proof 1 e Solution by
Codex 0 2026-10-31
The unconstrained cases can be treated as don't-care conditions during Boolean function minimization. One particularly small, deliberately asymmetric choice isUse the same two history D flip-flops and one output D flip-flop, with this expression at the output D input. It requires two two-input AND gates and one OR gate.
To verify every required case, first set . If zero occurs at least twice among , then , so as required. If all three samples are one, then , so . The remaining triples have exactly two ones and hence exactly one sample agreeing with the old zero; either output is allowed.
Now set . If at least two samples are one, either or , giving . If all three samples are zero, both terms vanish, giving . The remaining triples have exactly one one and are the allowed don't-care conditions. Thus the expression meets both requirements, including every constant-input triple.
For minimality, consider these required one-entries in order: , , and have no common literal. Therefore a product covering all four would be the constant one, which violates required zero-entries. Also no single-literal product is safe: each of is one at some required zero-entry, and each complemented literal is one at . Hence at least two products with at least two Boolean literals each are needed. The displayed expression attains two products and four literals.
Past exam of the year 1 of the computer science course of the University of Oxford 2013 Digital systems, linear algebra, introduction to formal proof 1 d Solution by
Codex 0 2026-10-31
Keep the two history D flip-flops and add an output D flip-flop with previous value . Its next value is one if all three inputs are one, or if the output was one and at least one of the three inputs is one. In the latter case the samples are not all zero, so the previous one must be retained. This givesIf , the first product sets the output. If , every product vanishes and the output clears. For every mixed input triple, at least one of equals , so the output is retained. Feed this sum of products to the output D input, use for the history, and use asynchronous clear or an appropriate initialization to establish .
Minimality can be seen directly from the truth table. At , the only one-entry is , forcing the product or a narrower term. At , the triples , and must all produce one; combining any two in one product would also admit , which must produce zero. Thus three more products are needed. The displayed four products achieve the minimum; removing any Boolean literal from would include a zero-entry.
Past exam of the year 1 of the computer science course of the University of Oxford 2013 Digital systems, linear algebra, introduction to formal proof 1 c Solution by
Codex 0 2026-10-31
Use two history D flip-flops. Write , and for the signals just before the active clock edge; update the history by and . Two or more of the three samples are one exactly when some pair are both one, so the majority function isThree two-input AND gates and one three-input OR gate implement this disjunctive normal form. If a registered output is wanted, feed the expression to the D input of another D flip-flop and capture it at the same edge as the history update. All right-hand sides use the pre-edge values, so no extra sample of delay is introduced.
The three terms are necessary in a minimal sum of products: the input triples , and must each be covered, and a single product covering two of them would also cover a triple having only one one. Thus the minimum is three products, each with two Boolean literals.
Sample history and registered output for the three digital smoother designs
. Details. Past exam of the year 1 of the computer science course of the University of Oxford 2013 Digital systems, linear algebra, introduction to formal proof 1 b Solution by
Codex 0 2026-10-31
A serial-in parallel-out shift register is a chain of digital registers driven by the same clock signal. At each active clock edge, the first stage captures the input and every later stage captures the preceding stage's old value. Its parallel outputs expose the successive delayed samples simultaneously.
Let be the current sample and, immediately before its sampling edge, let . Feed these signals to combinational logic implementing . ThenOnly stored history stages are needed if the current input is used directly. Alternatively, a -stage shift register exposes all samples after the edge. A separate output digital register can capture the first arrangement at the edge, giving a fully sampled output. Initialize the history, or regard the first cycles as a filling interval.
Past exam of the year 1 of the computer science course of the University of Oxford 2013 Digital systems, linear algebra, introduction to formal proof 1 a Solution by
Codex 0 2026-10-31
A disjunctive normal form, also called a sum of products, is an OR of AND terms, each made from Boolean literals such as or . For example,Here juxtaposition means logical conjunction, means logical disjunction, and a bar means negation. The expression need not be canonical: a term can omit variables, and need not name a single row of the truth table.
Implement each product by an AND gate and combine the products with an OR gate. Supply complemented inputs with NOT gates. ThusThis is the usual two-level combinational logic realization, counting complemented inputs as available. If NOT gates are counted, a complemented input can traverse three gates. The two-level depth statement also assumes sufficiently large gate fan-in: using only two-input logic gates requires trees for long products or sums. Constant, single-product and single-literal Boolean functions may need fewer levels, so the two-level construction is a general bound, not a claim that every expression requires exactly two layers.
Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 9 b Solution by
Codex 0 2026-10-31
The printed word “even” conflicts with the displayed numbers: all ten listed prime numbers are odd, and is the only even prime number. The scan confirms that wording.[ref]
Functional programming, data structures and algorithms, procedural programming, and digital hardware examination paper by the University of Oxford (2005). Printed p. 5, Question 9(b), both occurrences of “even” and the final “including 2”
We first construct the detector for the explicitly listed numbers, then add as requested. The literal even-prime detector is also given below.Let the five input bits be with value . Every listed number has . For that plane, the four-variable Karnaugh map is
The entire plane is zero. Five valid groups in the displayed Karnaugh map give the product termsIncluding , their accepted numbers are respectively , , , , and . Their union is exactly the ten listed numbers. Hence an explicit Boolean circuit is: invert where needed, feed the five products into five AND gates, combine those outputs with an OR gate, and AND with . Its output isAny gate with more than two inputs can be replaced by a tree of two-input gates. To include the exceptional prime number , detect its exact binary representation and add one OR branch:If “even prime” is read literally instead of following the listed numbers, the complete first detector is simplyAll three formulas classify all possible inputs, including and as nonprime.
Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 9 a Solution by
Codex 0 2026-10-31
Write for a two-input NAND gate. Three elementary constructions areThe last identity is De Morgan's laws. To see that these operations suffice from first principles, take any finite truth table. For each row whose output is , form the conjunction of input literals that matches exactly that row: use when the row has , and when it has . Disjoin all such conjunctions. On any input, precisely its matching row conjunction can be true, so this disjunctive normal form equals the desired Boolean function.
Replace each negation, conjunction and disjunction by the displayed NAND gate constructions, nesting two-input gates for longer conjunctions or disjunctions. Constant outputs are available too: for any input , , and NANDing that value with itself gives . ThusA zero-input constant circuit additionally needs a supplied constant signal, such as a fixed logic supply. The positive-arity construction already covers constant-valued Boolean functions having one or more unused inputs.
For a three-input CMOS NAND gate, put three PMOS transistors in parallel from the positive supply to the output , and three NMOS transistors in series from to ground. Each input controls one device in each network:
A high input turns on its NMOS transistor and turns off its PMOS transistor; a low input does the opposite. If , every series NMOS transistor conducts and every PMOS transistor is off, pulling low. If any input is zero, its NMOS transistor breaks the series path and its PMOS transistor provides a path to , pulling high. ConsequentlyFor ideal settled inputs, the complementary networks do not simultaneously connect supply to ground. The CMOS arrangement gives a driven high or low output in every input case, rather than leaving the output floating.
Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 8 b Solution by
Codex 0 2026-10-31
Add polynomials by adding equal-power coefficients, interpreting a missing coefficient as zero. Compute into a local record before assigning the output, so the result may safely be the same actual record as either input.
PROCEDURE Add(VAR p, q, result: Polynomial);
VAR t: Polynomial; i: INTEGER; u, v: REAL;
BEGIN
t.len := p.len;
IF q.len > t.len THEN t.len := q.len END;
i := 0;
WHILE i < t.len DO
u := 0.0; v := 0.0;
IF i < p.len THEN u := p.coeff[i] END;
IF i < q.len THEN v := q.coeff[i] END;
t.coeff[i] := u+v;
i := i+1
END;
result := t
END Add;With , the loop invariant is and, for ,
t.coeff[k] is the sum of the two extended input coefficients at . The loop variant is . The inputs remain unchanged throughout the loop, and at exit every active coefficient is correct. The time complexity is for the active arithmetic; assigning the fixed-capacity record can additionally copy its full capacity.For the product, each pair of input terms contributes . Initialize the active result to zero, then accumulate these pairwise contributions:
PROCEDURE Multiply(VAR p, q, result: Polynomial);
VAR t: Polynomial; i, j, k: INTEGER;
BEGIN
t.len := 0;
IF (p.len > 0) & (q.len > 0) THEN
t.len := p.len + q.len - 1
END;
(* Precondition: t.len <= Capacity. *)
k := 0;
WHILE k < t.len DO
t.coeff[k] := 0.0; k := k+1
END;
IF t.len > 0 THEN
i := 0;
WHILE i < p.len DO
j := 0;
WHILE j < q.len DO
t.coeff[i+j] := t.coeff[i+j]
+ p.coeff[i]*q.coeff[j];
j := j+1
END;
i := i+1
END
END;
result := t
END Multiply;The input representation invariants and the capacity precondition are assumed. No coefficient is accessed when either input is the zero polynomial. The initialization loop invariant says coefficients below are zero; its loop variant is
t.len-k.For positive input lengths , the outer loop invariant says that and each coefficient equalsThe inner loop invariant adds the contributions with and to that sum, while . The update adds exactly the next missing term at index , preserving the inner loop invariant. The loop variants are for the outer loop and for the inner loop. On exit all pairs have contributed, yieldingThe product uses arithmetic operations and a temporary coefficient array of capacity
Capacity. Both operations allow trailing zeros; no extra normalization loop is required. Only the active coefficients are meaningful, so inactive record entries are never read by these operations. As in part (a), floating-point coefficients implement these formulas subject to rounding. Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 8 a Solution by
Codex 0 2026-10-31
Use an Oberon record containing an active coefficient count and a bounded array of coefficients in ascending power order. A count of zero represents the zero polynomial; a count represents . Trailing zero coefficients are allowed, so the count need not be the degree of a polynomial plus one.
CONST Capacity = 1024;
TYPE Polynomial = RECORD
len: INTEGER;
coeff: ARRAY Capacity OF REAL
END;
PROCEDURE Horner(VAR p: Polynomial; x: REAL): REAL;
VAR i: INTEGER; value: REAL;
BEGIN
i := p.len; value := 0.0;
WHILE i > 0 DO
i := i-1;
value := p.coeff[i] + x*value
END;
RETURN value
END Horner;The representation invariant is , with only indices below
len significant. The parameter is passed by reference to avoid a full record copy; the procedure does not modify it.Let be the original coefficient count. At each guard test the loop invariant isThe empty sum is zero initially. If the old index is , after decrementing and updating,which preserves the loop invariant. The loop variant is , decreasing by one until zero. At exit,This is exactly the right-to-left nesting of Horner's method, matching the supplied right fold. It uses arithmetic operations and additional scalar storage.
REAL gives ordinary floating-point evaluation; the displayed identities specify the ideal arithmetic calculation, with the usual rounding in an actual floating-point implementation. Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 7 b Solution by
Codex 0 2026-10-31
Each merge consumes and copies a total of elements, so its time complexity is . HenceAt any level of the recursion tree, all active subranges are disjoint and together contain at most elements. The total work per level is therefore , and halving gives levels. In fact the full run performs work for .
The shared work array holds elements, and the depth-first recursion has simultaneous activation records with a constant number of scalar variables each. No recursive call allocates a fresh array. ThereforeThe work array is counted in the auxiliary space complexity even though the caller supplies it. If its actual allocated capacity is , the reserved storage is ; choosing capacity gives the stated bound.
Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 7 a Solution by
Codex 0 2026-10-31
Represent the two recursively split arrays by adjacent half-open ranges of the original array. This avoids allocating a fresh pair at every call. The caller supplies a distinct work array with at least as many elements as
a; only that work array is used for merging. The Oberon code isPROCEDURE SortRange(VAR a, work: ARRAY OF INTEGER;
l, r: INTEGER);
VAR m, i, j, k: INTEGER;
BEGIN
IF r-l > 1 THEN
m := l + (r-l) DIV 2;
SortRange(a, work, l, m);
SortRange(a, work, m, r);
i := l; j := m; k := l;
WHILE (i < m) & (j < r) DO
IF a[i] <= a[j] THEN
work[k] := a[i]; i := i+1
ELSE
work[k] := a[j]; j := j+1
END;
k := k+1
END;
WHILE i < m DO
work[k] := a[i]; i := i+1; k := k+1
END;
WHILE j < r DO
work[k] := a[j]; j := j+1; k := k+1
END;
k := l;
WHILE k < r DO
a[k] := work[k]; k := k+1
END
END
END SortRange;
PROCEDURE MergeSort(VAR a, work: ARRAY OF INTEGER);
BEGIN
SortRange(a, work, 0, LEN(a))
END MergeSort;For a range of length , the left length is and the right length is , so as required. Both are positive and smaller than , giving the recursive loop variant analogue for algorithm termination. Empty ranges are also harmless, although the question supplies a nonempty array.
For the first merge loop, regard the two sorted ranges as fixed input sequences and . They are not overwritten during the merge. A loop invariant is that , , , and
work[l:k) is the stable sorted merge of the consumed prefixes a[l:i) and a[m:j). Every emitted element is at most every remaining element. Taking the smaller head preserves this property, and choosing the left head on equality preserves stable sorting. The loop variant isIt is nonnegative and decreases by one per iteration. On exit at least one range is exhausted.For the second loop, the remaining left range is already sorted and any right remainder is absent whenever that loop runs. Appending the next left element preserves the same merge loop invariant; its loop variant is . For the third loop, the left range is exhausted and the right remainder is appended in order; its loop variant is . On completing both loops,
work[l:r) is the complete sorted merge and .In the final copying loop, the loop invariant is that
a[l:k) equals work[l:k), work[l:r) remains the correct sorted answer, and positions outside a[l:r) are unchanged. Its loop variant is . At exit the whole answer has been copied back. By strong induction on range length, the recursive calls sort their halves, and the merge preserves the original multiset. ThusThe work array must not alias a: overwriting the source while merging would invalidate the merge loop invariant. Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 6 c Solution by
Codex 0 2026-10-31
Replace the recursive transfer in part (b) by simultaneous state updates, using a temporary variable to preserve the old
a:PROCEDURE FibIter(n: INTEGER): INTEGER;
VAR k, a, b, oldA: INTEGER;
BEGIN
k := n; a := 1; b := 0;
WHILE k > 1 DO
oldA := a;
a := a + b;
b := oldA;
k := k - 1
END;
RETURN a
END FibIter;For original input , a loop invariant isIt holds initially because . Each iteration preserves it by the identity from part (b). The loop variant is , a nonnegative integer that decreases by one whenever the guard holds. On exit , so the loop invariant gives , exactly the returned answer. The procedure uses arithmetic operations and stored integer variables, without depending on compiler treatment of tail calls.
Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 6 b Solution by
Codex 0 2026-10-31
In tail recursion, each recursive call is a tail call: its result is returned directly, with no suspended addition or other work. A compiler can then reuse an activation record, giving constant stack use. This is a possible optimization, not a guarantee made by the source syntax. The direct Fibonacci number procedure in part (a) must retain information while waiting to add two recursive results.
Extend the Fibonacci numbers with and use the suggested quantity . For ,while . This gives the Oberon procedures
PROCEDURE G(n, a, b: INTEGER): INTEGER;
VAR result: INTEGER;
BEGIN
IF n = 1 THEN
result := a
ELSE
result := G(n-1, a+b, a)
END;
RETURN result
END G;
PROCEDURE FibTail(n: INTEGER): INTEGER;
BEGIN
RETURN G(n, 1, 0)
END FibTail;The assignment of the recursive result does not perform arithmetic after the call; it merely passes that result to
RETURN, so the call is in tail recursion. A dialect permitting an immediate RETURN G(...) in the branch expresses the same control flow. The decreasing argument proves algorithm termination, and the displayed identity proves correctness by mathematical induction. ThusThere are recursive steps, giving arithmetic operations. Stack use is with tail call elimination and without it. With unbounded integers, the growing Fibonacci numbers also make arithmetic costs grow; the linear bound counts arithmetic operations. Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 6 a Solution by
Codex 0 2026-10-31
An Oberon recursive procedure can implement the defining recurrence relation directly. Its precondition is ; arithmetic is assumed to remain in the representable integer range.
PROCEDURE Fib(n: INTEGER): INTEGER;
VAR result: INTEGER;
BEGIN
IF n <= 2 THEN
result := 1
ELSE
result := Fib(n-1) + Fib(n-2)
END;
RETURN result
END Fib;Correctness follows by strong induction: the two base inputs give , and for the returned sum is . On each recursive branch the positive integer argument strictly decreases, while recursion stops at or . The well-ordering principle therefore proves algorithm termination.The method repeats many subproblems and has exponential time complexity; termination alone does not make it efficient.
Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 5 b Solution by
Codex 0 2026-10-31
Heapsort uses time for bottom-up heap construction and for each extraction, giving worst-case time complexity. An iterative heapify down on an array uses auxiliary space complexity. Ordinary heapsort is not a stable sorting method.
Quicksort has balanced-case and average-case time complexity when the input order supplies suitably distributed pivot ranks. With the prescribed first-element pivot, sorted inputs produce subproblems of sizes and , giving . With the stated two-way partition convention, all-equal keys also give this worst case. There is no input-independent expected bound without a distribution or randomization assumption. For an in-place array implementation, the recursion stack is when balanced and in the worst case; the functional list trace also allocates new partition spines and copied concatenation prefixes. Ordinary in-place quicksort is not stable sorting; the stable-partition list convention used in the trace can preserve equal-key order at additional allocation cost.
Counting sort uses time complexity for possible consecutive integer keys. The stable sorting version uses auxiliary space complexity including the output array; counting and re-emitting bare keys needs only beyond its output. It is attractive when is small, but a sparse huge key range makes both initialization and count storage expensive. It relies on indexing by bounded integer keys, so it is not subject to the comparison sorting lower bound.
Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 5 a Solution by
Codex 0 2026-10-31
For heapsort, use the usual array representation of a max-heap, indexed from zero, with children . Build the max-heap from the last internal node towards the root, using heapify down. The three build stages are
start [2,7,3,2,8,1]
sift at index 2 [2,7,3,2,8,1]
sift at index 1 [2,8,3,2,7,1]
sift at index 0 [8,7,3,2,2,1]At index zero, the value
2 moves below 8 and then below 7. Next exchange the root with the last active element, shorten the active heap, and restore heap order. A vertical separator below distinguishes the active prefix from its sorted final suffix.| Removed maximum | After root exchange | After restoring heap order |
|---|---|---|
1,7,3,2,2 | 8 | 7,2,3,1,2 | 8 | |
2,2,3,1 | 7,8 | 3,2,2,1 | 7,8 | |
1,2,2 | 3,7,8 | 2,1,2 | 3,7,8 | |
2,1 | 2,3,7,8 | 2,1 | 2,3,7,8 | |
1 | 2,2,3,7,8 | 1 | 2,2,3,7,8 |
The trace chooses the left child when equal children tie; other tie conventions can give different intermediate heaps with the same sorted output.
For quicksort, use the head as pivot and partition the remaining elements into those strictly less than it and those greater than or equal to it, retaining their order within each partition. This specifies how the duplicate
2 is handled:pivot 2: [1] | 2 | [7,3,2,8]
pivot 7: [3,2] | 7 | [8]
pivot 3: [2] | 3 | []Empty and singleton lists are already sorted. Returning from the recursive calls gives
Q [3,2] = [2] ++ [3] ++ [] = [2,3]
Q [7,3,2,8] = [2,3] ++ [7] ++ [8] = [2,3,7,8]
Q [2,7,3,2,8,1] = [1] ++ [2] ++ [2,3,7,8]initial: (0,0,0,0,0,0,0,0)
read 2: (0,1,0,0,0,0,0,0)
read 7: (0,1,0,0,0,0,1,0)
read 3: (0,1,1,0,0,0,1,0)
read 2: (0,2,1,0,0,0,1,0)
read 8: (0,2,1,0,0,0,1,1)
read 1: (1,2,1,0,0,0,1,1)The cumulative counts are . For the usual stable sorting version with zero-based output indices, scan the input from right to left, place a key at position , and decrement . The successive placements are
1 at , 8 at , the later 2 at , 3 at , 7 at , and the earlier 2 at . The final answer for all three sorting algorithms is Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 4 c Solution by
Codex 0 2026-10-31
In the coin change problem, take denominations and target amount . The natural greedy algorithm repeatedly chooses the largest denomination not exceeding the remaining amount. It chooses , then , then , for three coins. Yet uses only two.
Two is optimal: one coin cannot make because denomination is absent, and the displayed pair attains the lower bound. ThereforeThe locally largest first coin loses the possibility of using the better pair of threes. This supplies a concrete failure of the greedy-choice property; optimal substructure alone does not justify the greedy choice. The dynamic programming recurrence from part (b) would compare all feasible first or last denominations and find the pair.
Past exam of the year 1 of the computer science course of the University of Oxford 2005 Functional programming, data structures and algorithms, procedural programming, and digital hardware 4 b Solution by
Codex 0 2026-10-31
Divide-and-conquer algorithms suit problems with largely independent, balanced subproblems and an inexpensive combination step. In merge sort, the two halves are independently sorted and merged in linear time. Its recurrence relation is , giving time complexity.
Dynamic programming suits overlapping subproblems with a compact state description. For the coin change problem, let be the minimum number of coins needed to make amount . With positive denominations containing ,Every optimal nonempty answer has a last coin and an optimal answer for ; otherwise replacing the remainder improves it. Filling takes time complexity and space complexity. Repeated amounts are computed just once. This bound is in the numeric amount , not its binary input length.
A greedy algorithm suits problems where one can prove a greedy-choice property. For unweighted interval scheduling, choose an interval with earliest finishing time, discard overlapping intervals, and repeat. Among optimal schedules, replace the first interval by the earliest-finishing one. The replacement finishes no later, so every later interval remains feasible. Applying the same argument to the remaining intervals proves optimality. After sorting by finish time, a single scan suffices.
These examples separate the relevant structural reasons: independent halves, repeated amount states, and an exchange argument certifying each irreversible choice.
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







