Use 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
= xs
For a nonempty forest, write its first rose tree as Node 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)
Thus the recursive Haskell definition is
flatten2 :: [RTree a] -> [a] -> [a]
flatten2 [] xs = xs
flatten2 (Node r children : trees) xs =
  r : flatten2 children (flatten2 trees xs)
The 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 xs.
Compute either the common depth of the leaves of a rooted tree, or failure when the depths differ. A tree fold can return a 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        = Nothing
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. perfect 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.
A tree fold first folds every child rose tree, then supplies the resulting list and the current label to the combining function:
foldRTree :: (a -> [b] -> b) -> RTree a -> b
foldRTree f (Node x children) =
  f x (map (foldRTree f) children)
The label type 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.
The printed source gives the signature exampleRTree but binds exampleRTRee, with different capitalization. They are different Haskell names; the demonstration requires using one spelling consistently. This typo does not affect the tree fold definition.
Use the right fold definition 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 gives
xs ++ ys
= foldr (:) ys xs
= foldl (flip (:)) ys (reverse xs)
Set 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 (:)) [] xs
The derived Haskell definition is therefore
reverse :: [a] -> [a]
reverse = foldl (flip (:)) []
Each step prepends the next element to the accumulator. This is a left fold derivation from list concatenation, rather than merely a proposed implementation.
Again use structural induction on the finite list. At [], 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)
The penultimate equality uses the induction hypothesis. Thus 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.
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 xs = [], both sides reduce to foldl f e ys. For the constructor case, equational reasoning gives
foldl 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)) ys
The third equality uses the induction hypothesis with accumulator f 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.
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.
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:
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}
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.
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 most
The 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.
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.
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.
Let be the minimum number of stamps for total . Since denomination 1 is available, every nonnegative total is reachable. The dynamic programming recurrence is
Fill the table in increasing order of :
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]
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.
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.
Precompute the 26 cumulative counts using prefix sums. Then
and 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.
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.
Use counting sort with 26 counters, indexed by the character code minus the code for A. Scan the input to obtain each character's count, then emit that many copies in alphabetic order. Counting costs ; visiting 26 counters and writing outputs costs .
The comparison lower bound does not apply because the algorithm uses a fixed-size known alphabet and direct key indexing. It does not have to distinguish distinct-key orders by binary comparisons; for , distinctness is not even possible in this alphabet.

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