Scan candidate output integers in increasing order while maintaining the smallest possible witness:
spectrum(r,n):
    k = 1
    for i = 1,...,n-1:
        while r*k*k < i*i:
            k = k+1
        if r*k*k < (i+1)*(i+1):
            Out.Int(i)
The inner loop supplies the left inequality from part (a), and the final test checks the strict right inequality. This prints each qualifying integer once. The witness index never decreases and is at most after the inner loop, so its total number of increments is at most . Consequently the whole nonrecursive program uses integer arithmetic operations, not iterations of a fresh search. Exact products or overflow-safe comparisons are required; arbitrary-precision bit costs depend on operand sizes.
For , , and integer , all terms are nonnegative, so squaring preserves the inequalities:
This gives integer-square membership in a square-root Beatty sequence without evaluating a floating-point square root. Since , any witnessing satisfies .
Use Binet's formula entirely within . Set
Here pairs mean the rational and radical coefficients. An exact program using the preceding procedures is
z = mkRat(0,1); one = mkRat(1,1)
half = mkRat(1,2)
phi = mkIrr(half,half)
psi = mkIrr(half,negRat(half))
c = mkIrr(z,mkRat(1,5))
p = mkIrr(one,z); q = mkIrr(one,z)
for i = 0,...,n-1:
    minusQ = mkIrr(negRat(q.rat),negRat(q.irr))
    OutIrr(mulIrr(c,addIrr(p,minusQ)))
    Out.Ln()
    p = mulIrr(p,phi)
    q = mulIrr(q,psi)
At iteration , and , so the printed value is exactly . The irrational coefficient cancels algebraically, and the rational result is an integer. This prints ; to use the convention , initialize p=phi and q=psi. There are field operations, with growing arbitrary-precision arithmetic costs kept separate from that count.
First normalize fresh copies of the two components. The following output helpers print a reduced rational with no /1, suppress a zero radical term, and suppress a unit radical coefficient:
OutRat(q):
    Out.Int(q.num)
    if q.den != 1: Out.String("/"); Out.Int(q.den)

OutIrr(x):
    r = mkRat(x.rat.num,x.rat.den)
    b = mkRat(x.irr.num,x.irr.den)
    if b.num == 0:
        OutRat(r); return
    if r.num != 0: OutRat(r)
    if b.num < 0: Out.String("-")
    else if r.num != 0: Out.String("+")
    c = mkRat(abs(b.num),b.den)
    if c.num != c.den:
        OutRat(c); Out.String("*")
    Out.String("sqrt(5)")
Thus the examples print 1/2+1/2*sqrt(5) and 2; zero prints 0, and pure unit radicals print sqrt(5) or -sqrt(5). The positive-denominator invariant makes the coefficient sign test reliable. Input records are not mutated.
Represent by the pair in the quadratic field . Its multiplication rule is
The constructor copies both rational components, so later reduction through another pointer cannot change the constructed value:
PROCEDURE mkIrr(r,i: rational): irrational;
VAR z: irrational;
BEGIN
  NEW(z);
  z.rat := mkRat(r.num,r.den);
  z.irr := mkRat(i.num,i.den);
  RETURN z
END mkIrr;

PROCEDURE addIrr(x,y: irrational): irrational;
BEGIN
  RETURN mkIrr(addRat(x.rat,y.rat),addRat(x.irr,y.irr))
END addIrr;

PROCEDURE mulIrr(x,y: irrational): irrational;
VAR r,i: rational;
BEGIN
  r := addRat(mulRat(x.rat,y.rat),
              mulRat(mkRat(5,1),mulRat(x.irr,y.irr)));
  i := addRat(mulRat(x.rat,y.irr),mulRat(x.irr,y.rat));
  RETURN mkIrr(r,i)
END mulIrr;
The representation includes rational values when the second coefficient is zero; the supplied type name does not require every stored value to be irrational.
Use the ordinary fraction identities, returning fresh records rather than changing either argument:
PROCEDURE addRat(x,y: rational): rational;
BEGIN
  RETURN mkRat(x.num*y.den + y.num*x.den, x.den*y.den)
END addRat;

PROCEDURE mulRat(x,y: rational): rational;
BEGIN
  RETURN mkRat(x.num*y.num, x.den*y.den)
END mulRat;

PROCEDURE negRat(x: rational): rational;
BEGIN
  RETURN mkRat(-x.num,x.den)
END negRat;
Every result is reduced by mkRat. This preserves the representation invariant even if an input was initially unreduced, provided its denominator is nonzero. Aliasing between the arguments causes no problem because their fields are only read.
Divide numerator and denominator by their positive greatest common divisor, then fix the sign:
PROCEDURE reduce(x: rational);
VAR g: INTEGER;
BEGIN
  ASSERT(x.den # 0);
  g := gcd(ABS(x.num),ABS(x.den));
  x.num := x.num DIV g; x.den := x.den DIV g;
  IF x.den < 0 THEN
    x.num := -x.num; x.den := -x.den
  END
END reduce;
The denominator condition ensures , including when the numerator is zero. Dividing both components by the same nonzero integer preserves the fraction, and the final simultaneous sign change preserves it again. The resulting numerator and denominator are coprime; for zero the denominator becomes one.
Use the supplied pointer-to-record representation and allocate a fresh record:
PROCEDURE mkRat(n,d: INTEGER): rational;
VAR z: rational;
BEGIN
  ASSERT(d # 0);
  NEW(z); z.num := n; z.den := d;
  reduce(z);
  RETURN z
END mkRat;
The rational number constructor returns a value with positive denominator in lowest terms, using part (b). Zero is represented as . Arithmetic below uses exact integers, or inputs whose intermediate values fit the chosen implementation; fixed-width overflow would otherwise invalidate exact arithmetic.
For local sequence alignment without mismatches, let maximize the score of alignments of a suffix of each prefix of lengths , allowing both suffixes to be empty. Initialize and fill
Zero starts a new alignment; the remaining candidates append the possible last columns. The same optimal-substructure argument as before proves the recurrence. Because , an alignment with a negative-scoring leading portion can be improved by dropping that portion, which is exactly what the zero reset permits.
Return , since an optimal pair of substrings may finish before either full string ends. The time is for positive input lengths, with full-table space or linear rolling-row space for the score alone. If an alignment is wanted, start alignment traceback at a maximum entry and stop at zero. No mismatching diagonal is introduced.
Enumerate all pairs of contiguous substrings, run the global algorithm on each pair, and take the largest score, also allowing the empty alignment of score zero. There are substrings of the first input and of the second. Each call costs at most for positive lengths, giving the requested upper bound . Substrings are contiguous; enumerating arbitrary subsequences would be a different search.
Store one maximizing predecessor together with every table value. For alignment traceback, start at and follow these pointers:
  • emits x[i-1] opposite y[j-1]; the letters are equal because that diagonal candidate was allowed only on a match.
  • emits x[i-1] opposite a gap.
  • emits a gap opposite y[j-1].
Continue to , including boundary moves, then reverse the collected columns. Any deterministic choice among tied predecessors gives an optimal alignment. Each step decreases at least one index, so reconstruction costs additional time and output space. The full score table or predecessor table requires storage for positive lengths.
Let be the optimal score for aligning the complete prefixes of lengths . The boundary values and recurrence are
The last candidate is omitted when the letters differ. Fill rows or columns in increasing index order and return . The final-column cases in part (a) exhaust all legal alignments and each can be appended to an optimal smaller alignment, proving the recurrence by induction on .
There are entries and at most three constant-time candidates per interior entry. Thus the time is for positive , or including empty-input boundary cases, with the same full-table space bound. Computing only the score can reduce auxiliary storage to by retaining two rows. This is global sequence alignment without mismatches; admitting a diagonal move on unequal letters would solve a different problem.
Dynamic programming stores answers to overlapping subproblems so they can be reused. Its optimal substructure requirement, the principle of optimality, says that an optimal answer's remaining subproblem solution must itself be optimal once the final decision and state are fixed.
For global sequence alignment without mismatches, use the two prefix lengths as the state. A final column is either a letter of the first string opposite a gap, a gap opposite a letter of the second, or two equal letters. Removing that column leaves one of three smaller prefix problems. If its alignment were suboptimal, replacing it by a better alignment would improve the whole answer. Many different alignments reach the same prefix state, making reuse valuable. Unequal-letter columns and double-gap columns are forbidden, rather than assigned ordinary finite penalties.
The procedure is Borůvka's algorithm. In the first round, visiting singleton components in the order , the chosen edges are respectively
The set of new edges is : repeated selections of and insert no extra copy. The resulting two components are and . Each chooses in round two, producing the weight-36 tree from part (d). The within-round order of distinct insertions can therefore be , followed by in the next round; it need not be the globally sorted Kruskal order.
The required minimum spanning tree cut property says: for every nonempty proper subset , the unique minimum-weight edge crossing the cut belongs to every minimum spanning tree. Indeed, add this edge to a tree that lacks it. The resulting cycle contains another edge crossing the cut, which is strictly heavier; replacing that edge decreases the total weight.
For the general proof, assume all edge weights are distinct. Fix the components at the beginning of a round, as the given procedure does. Each selected edge is the unique lightest edge across one of their cuts, so belongs to every minimum spanning tree. Inductively, the entire selected set is contained in such a tree and is therefore acyclic. While there is more than one component, connectedness supplies an outgoing edge for each, so at least two components merge. The finite process terminates connected. A connected subgraph of a spanning tree must be that whole tree, proving that the returned set is a minimum spanning tree.
Processing by increasing weight, Kruskal's algorithm accepts of weight one and of weight two, then rejects of weight three because its endpoints are already connected. It accepts , , , skips , accepts , skips , and accepts . Seven accepted edges now connect all eight vertices.
The resulting minimum spanning tree is
The remaining heavier edges are unnecessary once the tree is complete. Distinct edge weights also imply that this minimum spanning tree is unique.
Figure 1.
Minimum spanning tree of weight 36 and its component-merging construction
. The solution highlights the seven selected edges. The second panel distinguishes the six distinct first-round choices from the joining edge fh selected in the second round. Details.
It is a greedy algorithm because it commits at every step to the cheapest remaining edge that can be added without creating a graph cycle, without revising earlier choices. The minimum spanning tree cut property explains why these locally cheapest admissible choices can be extended to an optimal spanning tree.
Kruskal's algorithm sorts the edges and accepts an edge precisely when it joins two currently different connected components of a graph. A disjoint-set data structure maintains those components:
Kruskal(V, E, w):
    A = empty set
    make one disjoint set for each vertex in V
    for (u,v) in E sorted by nondecreasing w:
        if find(u) != find(v):
            add (u,v) to A
            union(u,v)
            if size(A) == size(V) - 1:
                break
    return A
An accepted edge merges two trees of the current forest. An edge within one component would complete a graph cycle and is skipped. On connected input, after acceptances the forest is a spanning tree. For a one-vertex graph the empty set is already the answer.
A spanning tree is a connected acyclic subgraph containing every vertex of the original undirected graph. For a graph with vertices it has edges. A minimum spanning tree minimizes the sum of its edge weights over all spanning trees:
Connectedness guarantees existence for a finite graph; equal weights can permit several minimizers.
An infinite trace exists exactly when a directed cycle is reachable from , by the infinite walk criterion in a finite directed graph. Compute the reachable set with depth-first search, compute its strongly connected components, and return true if any component has at least two vertices or contains a self-loop. A singleton without a self-loop does not qualify.
If the test succeeds, follow a path from to the cycle and traverse the cycle forever. Conversely, an infinite trace in a finite graph repeats a vertex, producing a reachable nonempty closed walk and hence a directed cycle. Reachability, component construction and the self-loop check all scan adjacency lists only a constant number of times. The worst-case time is , with auxiliary space for a straightforward transpose-based implementation.
Because the vertex set is finite, at least one vertex occurs infinitely often, so is nonempty. Let belong to this set. After any chosen visit to , a later visit to exists; the intervening edges give a directed walk from to . After that visit to , a later visit to also exists, giving a walk in the other direction. Removing repeated portions gives directed paths if desired.
Thus every pair in is mutually reachable and belongs to the same strongly connected component. This proves the claimed inclusion, which need not be equality: an infinite walk can repeatedly follow one cycle while omitting other vertices in its component. This is the recurrence-set part of the infinite walk criterion in a finite directed graph.

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!
We have two killer features:
  1. 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-calculus
    Articles 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/derivative
  2. 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.
    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.
  3. https://raw.githubusercontent.com/ourbigbook/ourbigbook-media/master/feature/x/hilbert-space-arrow.png
  4. Infinitely deep tables of contents:
    Figure 6.
    Dynamic article tree with infinitely deep table of contents
    .
    Descendant pages can also show up as toplevel e.g.: ourbigbook.com/cirosantilli/chordate-subclade
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