Start Prim's algorithm at vertex , since the source does not specify a starting vertex. Write every undirected edge with its smaller endpoint first. With lexicographic tie-breaking, the accepted edges are , of total weight 9.
Initially is the cheapest crossing edge. The next minimum is a weight-two tie between and , so choose . Then the weight-two tie between and is resolved in favour of . Adding vertex exposes the weight-one edge , which is selected next. Finally precedes among the weight-three choices. Every accepted edge crosses from the existing tree to a new vertex, as required by the minimum spanning tree cut property. A different starting vertex can produce a different accepted-edge order; the displayed answer fixes that unspecified choice. The algorithm is named for Robert C. Prim.
Use a dynamic programming state indexed by an edge budget. Put and for , then for compute
Every route using at most edges either already uses at most , or ends with some edge whose preceding route uses at most . Conversely every finite candidate in the displayed equation is attained by such a route. This proves the hop-bounded shortest-route recurrence by induction on , even when weights are negative.
In each round, copy the previous distance row and relax every edge into the new row, always reading from the old row. An in-place pass would allow several new edges in one round and violate the edge budget. Store a predecessor record for every selected candidate, either a carry to or the incoming edge from . Following records backwards from and reversing the collected edges returns the actual optimum route; an infinite final distance means no feasible route exists.
Only vertices incident to an edge, together with , need distance fields. In a graph representation whose edges reference vertex records, initialise those fields by visiting both endpoints of every edge, then ; repeated initialisations are harmless. In each round, first copy old fields to new fields by another complete endpoint pass, and only then begin the relaxation pass. Copying the same endpoint several times before any relaxation also does no harm. Thus each round costs , with no scan of isolated vertices, and for the total is time. An implementation that instead initialises full arrays for all vertices has the conventional bound . For or no edges, only the empty route can succeed.
To realise reconstruction without a dense table, associate a persistent route record with each finite distance. A successful relaxation in round creates a record containing the new edge and a pointer to the old round's route record at its source; a carry shares its record. All reads use old-round records. At most such records are created, taking space, and the returned chain has at most edges. Distances alone need only two fields per relevant vertex.
Here “route” uses the standard edge-budget shortest-path convention permitting repeated vertices; a bounded budget prevents an arbitrarily long negative-cycle traversal. If “path” instead requires vertex simplicity with unrestricted negative weights, this recurrence does not enforce that extra restriction. With nonnegative weights, removing cycles gives a simple optimum within the same budget.
Let and replace every edge weight by . Call the supplied shortest-path routine once using these new weights, and return its path in the original graph. For every path ,
where is its number of edges. Positive original weights imply positive transformed weights, so a shortest route can be taken to be simple and has at most edges. Distinct integral original weights of paths differ by at least one. Thus if for simple paths, then
For equal original weights, the transformed comparison is exactly the comparison of hop counts. Therefore every transformed shortest path minimises original weight first and number of edges second, proving the integer-weight shortest-path tie-breaking lemma. The transformation costs time, followed by one subroutine call. Weights gain only bits; exact arithmetic should be used if multiplying machine-sized weights might overflow. If is unreachable, it remains unreachable.
The intermediate states of the Bellman-Ford algorithm depend on edge order. Specify in-place edge relaxation in lexicographic directed-edge order:
Starting with , the first pass changes the vector as follows; omitted relaxations make no change:
The next pass makes no change, allowing early termination. If all passes are performed, passes two through four retain .
For the synchronous convention, where every relaxation reads only the previous row, the Synchronous Bellman-Ford recurrence instead gives
Both conventions reach the same shortest distances. The algorithm's eponyms are Richard Bellman and L. R. Ford Jr..
The Dijkstra algorithm finalises vertices in the order . After finalising , tentative distances to are . Finalising sets the distance to to . Finalising sets the distance to to . Finalising improves the distance to to ; its edge to proposes and causes no improvement. The final distance vector in vertex order is . All weights are positive, so every finalisation is justified by the usual label-setting shortest-path algorithm invariant. The method is named for Edsger W. Dijkstra.
This version of Kadane's algorithm, named for Joseph Born Kadane, permits the empty subsequence. For , let be the maximum of zero and the weight of a contiguous subsequence ending exactly at position . Let be the best weight anywhere in the first positions. Use
A segment ending at either extends one ending at or starts at ; the zero candidate permits discarding a negative predecessor and the empty answer. Any best segment of the first positions either ends at or already occurs in the first . These two decompositions prove the dynamic programming equations by induction.
Here is an implementation returning endpoints, using zero-based indexing:
best_segment(a):
    end_weight = best_weight = 0
    start = best_lo = best_hi = 0
    for j in range(len(a)):
        trial = end_weight + a[j]
        if trial <= 0:
            end_weight = 0
            start = j+1
        else:
            end_weight = trial
        if end_weight > best_weight:
            best_weight = end_weight
            best_lo, best_hi = start, j+1
    return (best_lo, best_hi, best_weight)
There is exactly one addition per input element, hence additions and comparisons. Auxiliary storage is . The all-negative case retains interval and weight zero. The example returns and weight 8, hence the desired contiguous subsequence.
Capacity alone cannot say which items have already been used. For the 0-1 knapsack problem, let use only the first items, each at most once. Then
The two alternatives omit item or take it. In the latter case its remaining companions must solve the smaller problem using the first items; otherwise replacing them would improve the whole selection. Both branches reduce the item index, so taking item cannot take it again. This establishes the recurrence relation and optimal substructure.
Fill rows in increasing and return . There are entries with constant work each. Store the decisions for reconstruction; value-only computation uses space by keeping two rows, or by scanning capacities downwards in a single row. A forward scan in a single row would instead allow repetitions. Nonnegative integral weights suffice for this version, including zero-weight items, because the item index always decreases.
Use positive integral item weights and a nonnegative integral capacity. For the unbounded knapsack problem, define to be the best value with total weight at most . Then
The zero candidate is the empty selection, so unused capacity is allowed and an empty set of fitting items causes no problem. Every nonempty feasible selection has some last item ; removing one copy leaves a feasible solution at capacity . Its value is bounded by the corresponding candidate. Conversely, taking an optimal smaller selection and adding that item attains the candidate, proving the recurrence relation by optimal substructure. Positive weights make every dependency strictly smaller.
Fill capacities in increasing order. There are entries, each scanning items, so the dynamic programming takes time and storage. A winning item pointer at each capacity reconstructs the chosen multiplicities. These are capacity-dependent, pseudopolynomial bounds. For zero-weight items, any positive value makes the repetition problem unbounded; nonpositive-value zero-weight items may simply be discarded before using the recurrence.
For each segment retain its total weight , largest possibly-empty prefix weight , largest possibly-empty suffix weight , and largest possibly-empty internal contiguous weight . The maximum-subarray segment summary combines adjacent segments as
An empty segment has all four values zero. For a singleton of weight , use . The recursive procedure splits into halves, computes their summaries and applies these four formulas; the root's is the desired maximum weight.
To return an actual subsequence, attach half-open endpoints to each of . A prefix endpoint starts at its segment's left boundary, and a suffix endpoint ends at its right boundary, including empty prefixes and suffixes. Store the interval belonging to whichever candidate wins a maximum. The crossing candidate joins a left suffix to a right prefix, which meet at the split point; the other candidates keep their child endpoints. Choose an empty interval on ties at weight zero. Return the root's winning interval as a slice of the original input. This augmentation still has constant-size state and constant-time combinations.
For correctness, a prefix either stays inside the left half or consists of the entire left half and a right prefix. The suffix argument is symmetric. An optimal contiguous segment either lies in one half or crosses the split, in which case it consists of a left suffix and a right prefix. Each upper bound in the formulas is attained by its recorded candidate, proving exactness. Empty candidates ensure that an all-negative input returns the empty subsequence.
There are tree nodes, each using a constant number of additions and comparisons. The divide-and-conquer algorithm therefore takes time and stack space, plus the cost of copying the returned slice if a copy is required. In the stated example it selects zero-based interval of weight 8. Carrying all four summary values avoids rescanning the halves at each split.
Maintain the two largest entries of each segment, counting repeated values as separate entries. A singleton returns its value and a sentinel for its missing runner-up. Split a longer segment into two nonempty halves, recursively obtain and , and combine them by
For example, an implementation on an indexed sequence can use:
top2(lo, hi):
    if hi-lo == 1: return (a[lo], -infinity)
    mid = (lo+hi)//2
    (mL,sL) = top2(lo,mid)
    (mR,sR) = top2(mid,hi)
    if mL >= mR: return (mL, max(sL,mR))
    else:        return (mR, max(mL,sR))
The result is top2(0,n). The global maximum is one of the two child maxima. Once its side is identified, the global second maximum is either that side's runner-up or the other side's maximum; the displayed formula exhausts these possibilities. This proves the divide-and-conquer algorithm by induction on segment length. There are leaves and constant-cost combinations, so its time complexity is , with recursive stack space for balanced splits. A Maybe value can replace the formal sentinel for a generic ordered element type. If both largest entries are equal, both are returned; a second distinct value is a different specification.
For the first recurrence relation, the master theorem compares with . Since , the recursive leaves dominate and the answer is . More explicitly, the work at depth is , a growing geometric series that stops at depth , where its sum has that order.
For the second recurrence relation, each step subtracts two and adds one until reaching a base case. For integral there are steps, so and the answer is .
The third set of printed requirements is inconsistent. The specified base values and its recurrence relation give identically, as strong induction immediately verifies: . In particular , while the extra condition demands . Thus no function satisfies all the printed conditions. Dropping that extra inequality gives .
The likely intended growth calculation can nevertheless be made precise, without treating it as a solution of the contradictory data. On dyadic arguments put . Its equation has the general form
because has characteristic equation . The printed values force . With suitably different initial values, the condition for arbitrarily large instead requires , hence and , or . That last order describes corrected initial data, not the paper as printed. All three bullets belong to this single marked part.
Sort the two halves ascending, reverse the second, and concatenate to form a bitonic sequence:
sort :: Ord a => [a] -> [a]
sort []  = []
sort [x] = [x]
sort xs  = merge (sort as ++ reverse (sort bs))
  where (as,bs) = halve xs
For a power-of-two length greater than one, both halves are smaller powers of two. By induction, the recursive calls return ascending permutations of their respective inputs. Reversal makes the second half descending, so part (e)'s precondition holds and merge sorts their concatenation without losing entries. This proves both sortedness and sorting permutation preservation. Its recurrence relation is , so summing the levels gives time. Equal keys cause no difficulty; ascending and descending here permit equality. This is a bitonic sorting algorithm.
Apply the supplied bitonic-merging fact directly:
merge :: Ord a => [a] -> [a]
merge xs = rounds (levels (length xs)) xs
  where
    levels n
      | n <= 1    = 0
      | otherwise = 1 + levels (n `div` 2)
    order (x,y)
      | x <= y    = (x,y)
      | otherwise = (y,x)
    pass = unpairs . map order . pairs . riffle
    rounds 0 ys = ys
    rounds r ys = rounds (r-1) (pass ys)
For length , levels n = k. Each pass performs exactly the required shuffle and adjacent compare-exchange operations. The supplied fact therefore proves that rounds k yields ascending order from a bitonic sequence. Each pass preserves the multiset of entries and costs , giving time for . Length one needs no pass. The definition also harmlessly returns [] on empty input.
For the defined shuffle, count 52 = 8. The printed assertion about seven shuffles is inconsistent with the actual permutation. Number positions from zero. On an even length , a position moves to , while the last position stays fixed. Indeed, positions in the first half move to , and positions in the second half move to . Consequently the number sought is the multiplicative order of modulo :
count :: Int -> Int
count n
  | n < 0 || odd n = error "count: nonnegative even length required"
  | n <= 2 = 1
  | otherwise = go 1 (2 `mod` m)
  where
    m = toInteger n - 1
    go k r
      | r == 1    = k
      | otherwise = go (k+1) ((2*r) `mod` m)
Here the identity's period means the least positive number of applications, so the empty and two-element lists have period one. Since is odd, is invertible modulo , ensuring termination. Using Integer for residues avoids overflow in doubling; the mathematical correctness assumes the returned period fits Int. The algorithm uses one modular update per shuffle in the period, rather than constructing each shuffled deck.
For , , whereas , and are not congruent to one, ruling out every proper divisor of eight. After seven shuffles, the original position is at position , not back at .
Figure 1.
An eight-step position cycle under the 52-card perfect out-shuffle
. Details.
This single position already disproves a seven-step return; the modular calculation proves that the whole permutation returns after eight.
Interleave equal halves, or collect the first and second components of adjacent pairs:
riffle :: [a] -> [a]
riffle = unpairs . uncurry zip . halve

unriffle :: [a] -> [a]
unriffle = unhalve . unzip . pairs
For halves as and bs of equal length, pairs (riffle xs) = zip as bs, and unzip (zip as bs) = (as,bs). Therefore unriffle (riffle xs) = xs. Conversely, starting from the adjacent pairs of any even list, separating the components, halving their concatenation and zipping them restores those same pairs. Hence riffle (unriffle xs) = xs too. Every stage takes linear time. This perfect out-shuffle leaves the first and last positions fixed.
Join either two halves or successive pairs:
unhalve :: ([a],[a]) -> [a]
unhalve (xs,ys) = xs ++ ys

unpairs :: [(a,a)] -> [a]
unpairs = foldr (\(x,y) zs -> x:y:zs) []
By the defining property of splitAt, concatenating the two halves restores the original list. For unpairs, structural induction on the even input proves that its first pair restores its first two elements and the recursive result restores the rest. Thus both requested function compositions are the identity. Fully consuming either result takes at most linear time; list concatenation only copies the left half once.
For finite even lists, these definitions take at most linear time:
halve :: [a] -> ([a],[a])
halve xs = splitAt (length xs `div` 2) xs

pairs :: [a] -> [(a,a)]
pairs [] = []
pairs (x:y:xs) = (x,y) : pairs xs
pairs [_] = error "pairs: odd length"
The length calculation and the prefix split each take time. The second operation consumes two constructors per step and emits one pair. Under the stated even-length precondition, neither definition encounters an unmatched final element.
A compatible Ord instance supplies a total order, so use comparison sort to put equal values together in time and then group adjacent equals in linear time. To preserve the first-occurrence group ordering of part (f), first tag every element with its original index and stable sorting by value. Group the sorted records by value; stability preserves their internal input order. Each group's first record carries its smallest original index. Sort the groups by that index and finally remove the tags. The second sort has at most records, so the total remains time and storage. Merely returning the value-sorted groups could reorder the classes, so the index step matters when preserving the exact earlier convention. The stronger interface evades the equality-only lower bound by permitting order comparisons.
Choose the first unclassified element as the next equivalence class representative:
equiv :: Eq a => [a] -> [[a]]
equiv [] = []
equiv (x:xs) = (x:same) : equiv rest
  where ~(same,rest) = partition (== x) xs
Assume the Eq instance is an equivalence relation. The stable list partition collects every later occurrence equivalent to x, and rest contains none of that equivalence class. Induction therefore gives exactly one group per class, preserving order within each group and ordering groups by their first occurrence. For distinct classes, each input element is tested against at most representatives: the cost is and in the all-distinct worst case; a single class takes .
The equality-only grouping lower bound shows that this worst case is unavoidable in the unrestricted equality-oracle model. On an all-distinct input, an untested pair could instead be equal without changing any observed comparison. Certifying that all elements belong to different classes therefore requires all pairwise equality tests.
Share the recursive pair and inspect the predicate once:
partition :: (a -> Bool) -> [a] -> ([a],[a])
partition _ [] = ([],[])
partition p (x:xs)
  | p x       = (x:yes,no)
  | otherwise = (yes,x:no)
  where ~(yes,no) = partition p xs
For a finite list, structural induction establishes that yes and no are the two required filtered subsequences. The guard evaluates p x once and prepends x to exactly one output, preserving input order in both. Fully consuming both results uses predicate applications and additional work. Sharing the recursive result avoids making separate recursive traversals. This is a stable list partition.

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