Past exam of the mathematics course of the University of Cambridge 2010 ia Paper 4 5E Solution Created 2026-09-24 Updated 2026-10-14
For the Fibonacci addition formula, use mathematical induction on , with the assertion applying to every . At , . If the formula holds for some and all , apply it at and use the Fibonacci number recurrence:This is the assertion at , completing the mathematical induction. ThusTaking gives the doubling identity
For the Lucas numbers, , and . For , both expressions for earlier Lucas numbers are available, andHence . The separate check matters because the defining expression for was given separately.
The Euclidean algorithm and the Fibonacci number recurrence give, for ,Repeating reduces to ; the case is immediate. Therefore .
For , , so a common divisor of divides both and . Since are coprime, Bézout's identity gives integers with . Multiplying by shows . Conversely any common divisor of and divides . Including , this proves the stronger greatest common divisor identity
Past exam of the mathematics course of the University of Cambridge 2016 iii Paper 204 2 b Solution Created 2026-10-03 Updated 2026-10-06
Represent the doubly infinite ladder graph by , with horizontal edges between successive columns and a vertical rung at each column. An allowed self-avoiding walk is coded by a word in . Two successive steps revisit the preceding graph vertex and are forbidden. Conversely, every word without consecutive steps is a self-avoiding walk: horizontal steps strictly increase the column, and a column is visited vertically at most once. This establishes a bijection, not merely an upper bound.
For the directed ladder self-avoiding walk count, , , and for a word either ends in , or ends in . Removing that final block givesLet be the golden ratio, and . The Binet formula for the Fibonacci number yieldsSince , taking th roots gives . This use of the golden-ratio symbol is independent of the connection rate in Question 1.
Past exam of the mathematics course of the University of Cambridge 2019 ia Paper 4 5E c i Solution Created 2026-09-24 Updated 2026-10-03
True. Write the odd integer as . The identity from part (b) and giveConsecutive Fibonacci numbers are coprime, so is invertible modulo . HenceThus is a quadratic residue modulo the odd prime , which occurs exactly when .
Past exam of the mathematics course of the University of Cambridge 2021 ia Paper 4 2E ii Solution Created 2026-09-24 Updated 2026-09-25
The stated formula is Cassini's identity. It holds for , and the recurrence giveswhich is the negative of the expression at index . This proves the identity by induction.
Past exam of the mathematics course of the University of Cambridge 2021 ia Paper 4 2E i Solution Created 2026-09-24 Updated 2026-09-25
The Fibonacci recurrence givesThe map is strictly decreasing for . Since , applying this decreasing map reverses each inequality and proves by mathematical induction thatTaking even shows , so is a decreasing sequence.
Past exam of the mathematics course of the University of Cambridge 2022 ia Paper 4 6D c Solution Created 2026-09-24 Updated 2026-09-25
PutThe initial values are . Using Pascal's identity and the convention that an out-of-range binomial coefficient is zero,Thus has the same initial values and linear recurrence relation as the Fibonacci numbers. Mathematical induction gives
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.Keep the neighboring Fibonacci number in a private closure. Before calling the transition with , let its captured The transition returns and stores , preserving the paired Fibonacci recurrence. Initialization gives and , soUsing
following equal .def fibonacci(): Iter[BigInt] = {
var following = BigInt(1)
val step: BigInt => BigInt = (x: BigInt) => {
val result = following
following = x + following
result
}
new FunIter[BigInt](BigInt(0), step)
}BigInt allows all Fibonacci numbers rather than a finite prefix before integer overflow. Replacing BigInt by Int gives the source's suggested machine-integer interface with that limitation. With the FunIter implementation from part (c), each transition runs once per generated cell, and copied iterators can advance independently while sharing the privately owned generator. A simpler alternative uses a pure function on pairs, , and projects the first component; the closure above follows the source's suggested single-value approach directly.Keep the two adjacent Fibonacci numbers in one shared pair. From the Fibonacci recurrence, if the current pair is , the next is . This gives the paired Fibonacci recurrence:
twoFibs :: Integer -> (Integer, Integer)
twoFibs 0 = (0, 1)
twoFibs n
| n > 0 = let (a, b) = twoFibs (n - 1)
in (b, a + b)
| otherwise = error "negative Fibonacci index"
fib :: Integer -> Integer
fib = fst . twoFibsThe pair pattern shares the result of the single recursive call. Mathematical induction establishesThere are pair updates and additions, rather than the repeated subcomputations of the original branching recursion. This is linear arithmetic-operation count; exact Fibonacci numbers have growing bit length. The pattern
fib (n+2) in the source expresses the recurrence; the guarded definition above uses ordinary Haskell syntax without requiring an n+k pattern extension.Let . The equations derived in part (e) become and , where . Replacing zero and successor by that seed and step is exactly a natural-number fold:
twoFibsNat :: Natural -> (Integer, Integer)
twoFibsNat = foldNat step (0, 1)
where
step :: (Integer, Integer) -> (Integer, Integer)
step (a, b) = (b, a + b)
fibNat :: Natural -> Integer
fibNat = fst . twoFibsNatConsequentlyStructural induction follows the constructors of
Natural: the seed gives the first two Fibonacci numbers, and the successor step uses the Fibonacci recurrence. The extra component carries exactly the information needed for the next update.Use a programming closure whose private variable holds the next Fibonacci number. Use arbitrary-precision integers to enumerate all terms exactly:At the cell containing , the private state immediately before computing its successor is
def fibonacci(): Iter[BigInt] = {
var following = BigInt(1)
val step: BigInt => BigInt = (current: BigInt) => {
val result = following
following = current + following
result
}
new FunIter[BigInt](BigInt(0), step)
}following = F_(i+1). The successor returns that value and sets following to , preserving the recursion invariant. The resulting sequence startsEach successor is computed once by the memoized implementation in part (c); interleaved copies see the same already generated successor instead of independently advancing shared programming closure state. Replacing BigInt by Int and the two initial values by 0,1 gives exactly the hinted Int => Int implementation, but eventually incurs integer overflow, so it does not enumerate all mathematical Fibonacci numbers.An alternative avoiding mutable programming closure state represents the current and next Fibonacci numbers by a pair and uses the pure function with initial state ; a projecting iterator returns the first component. The closure construction above meets the suggested one-number interface directly.
Suppose the formula holds at . Adding the next Fibonacci number with its sign and using the Fibonacci recurrence givesThis is the required successor case. Thus
Store two consecutive Fibonacci numbers as the state:
fibs :: [Integer]
fibs = unfold (const False) fst step (0,1)
where
step (a,b) = (b,a+b)The invariant is that the state is , with . Emitting its first component and updating the pair therefore produces .
Integer avoids fixed-width overflow; the bit cost of adding increasingly large integers is separate from the number of unfold steps.Give the step function one private previous-value cell, freshly allocated for each independent Fibonacci generator:
def fibonacci(): Iter[BigInt] = {
var previous = BigInt(1)
val step: BigInt => BigInt = { current =>
val following = previous + current
previous = current
following
}
new FunIter[BigInt](BigInt(0), step)
}The initial artificial previous value is , making the first update return one. Thereafter, just before advancing from , the captured cell holds ; the assignment produces and retains . Induction gives .
BigInt avoids the fixed-width overflow that would prevent Int from representing all Fibonacci numbers.Copies made through part (c) share memoized future cells, so interleaving their traversal does not advance this private state twice for the same sequence position. A separate call to
fibonacci() receives a separate closure. Another valid construction uses a pure step on the pair and projects the first coordinate; the stateful construction above follows the suggested single-current-value approach.The initial vector records both initial Fibonacci numbers: . For ,Conversely this vector recurrence forces the second component to be the preceding first component and forces their sum to be the next first component, recovering the scalar recurrence and its initial conditions. Iterating, or using mathematical induction, yields for every .
Fix and use two-base mathematical induction on . At , the proposed right side is ; at , it is . Suppose the identity holds at and . The defining recurrence relation for the Fibonacci numbers givesThis is the assertion at , completing the proof of the Fibonacci addition formula. The argument includes , since is defined.
Pisano period 2026-10-20
The Pisano period is the period of the Fibonacci number sequence in modular arithmetic modulo , with and . Consecutive residues evolve by the invertible update on a finite set, so the pair sequence returns to and is periodic from the start.
Primitive recursive pairing function Created 2026-10-06 Updated 2026-10-14
A primitive recursive pairing function is a pairing function whose encoding function and both coordinate functions of its inverse function are primitive recursive functions. Thus the bijection can be used in either direction inside a construction by primitive recursion and function composition in recursion theory. A decoder that is merely a computable function would not establish this stronger closure property. Sutner's definition of a primitive recursive pairing system explicitly includes the decoding functions; his more general systems need only be injective, whereas a pairing function here is a bijection.[ref]
https://www.cs.cmu.edu/~cdm/resources/02-coding.pdf. Klaus Sutner, Primitive Recursion, slide 9: primitive recursive encoding and unpairing functions
The Cantor pairing function is a primitive recursive pairing function. For its encoding, construct the triangular numbers directly by primitive recursion:Since addition is primitive recursive, so are and by primitive recursion and function composition in recursion theory. This establishes the claim without treating division by two as an unexplained primitive operation.
For decoding, use bounded minimization to defineThe bound is valid for every natural number : , so the candidate always succeeds. The search includes zero; when , it immediately returns . If , the preceding candidate failed, which gives ; when , that lower inequality follows from . Thus this search finds exactly the diagonal in the Cantor pairing function inverse, withThe comparison is primitive recursive, and bounded minimization of a primitive recursive predicate is primitive recursive. Therefore is a primitive recursive function. Recover the coordinates byIn constructions on the natural numbers, implement these subtractions using the primitive recursive operation : apply the predecessor function times to by primitive recursion. On these inputs it agrees with ordinary subtraction, since the diagonal inequalities imply . Consequently and are primitive recursive functions, and . Zimmermann proves the relevant closure under bounded minimization and the primitive recursive character of the Cantor encoding and coordinate decoding; his convention adds the first coordinate, so its coordinates are exchanged relative to here.[ref]
https://tore.tuhh.de/bitstream/11420/1312/1/book.pdf. Karl-Heinz Zimmermann, Computability Theory, §2.3, Proposition 2.26 and Propositions 2.32–2.34, printed pages 18 and 21–22
For a worked bounded minimization, take . Candidates give , none exceeding . Candidate gives , so , , and . The search bound was ; it terminates much earlier in this example. The bound proves membership in the primitive recursive functions; it is not a claim that scanning all candidates is the fastest implementation.
For each fixed , define a tuple encoder byEach and each coordinate decoder is primitive recursive, by finitely many applications of function composition in recursion theory to . For the three-entry tuple encoded as , applying returns , applying returns , and then , . The tuple length remains part of the agreed convention, as explained for a general pairing function.
This makes primitive recursive pairing functions useful for encoding several evolving values as one state in primitive recursion. For example, store consecutive Fibonacci numbers as and update byThe codes start , decoding to . Every step uses primitive recursive encoding, decoding and addition; a single numerical state therefore carries the two values needed for the next step. This is also the reason a suitable Gödel numbering should permit sufficiently simple decoding: representation should preserve the class of functions being studied.
Stateful channel iteration and Fibonacci numbers Created 2026-10-25 Updated 2026-10-31
Consider a component that remembers its previous input and maps input to , then sets . Feeding each output back into the same component gives state transition . Starting at , the successive outputs are , the Fibonacci numbers after calls. The state transition, rather than a memoryless function on one integer, explains the recurrence. Replacing the component between calls or repeatedly feeding a fixed external input gives different behavior.
Two-coefficient reduction of matrix powers 2026-10-18
Consider the real matrixThe Cayley-Hamilton theorem gives . ConsequentlyThusAll four entries come from just two scalar coefficients. If , multiplying once by and replacing gives the linear recurrence relationEquivalently , with . The appearance of Fibonacci numbers is explained by , where advances the Fibonacci recurrence. No eigenvectors need to be computed.
Cayley–Hamilton reduces powers of a chosen two-by-two matrix to two integer coefficients; the fifth power is 55A − 21I
. Details. The same identity computes an inverse. Rearrange it as , givingThis works because the constant term of this characteristic polynomial is nonzero and the coefficients lie in a field. Generally, when over a field, rearranging the Cayley-Hamilton theorem expresses as a polynomial evaluated at a matrix. Over a general commutative ring, a nonzero constant need not be a unit; invertibility requires that extra condition.
