Fibonacci Iterator
EasyUpdated: Sep 18, 2025
Problem
Write an iterator that yields all Fibonacci numbers up to a given upper bound top. Use it to:
- get the highest Fibonacci number less than
1000(expected987), and - find whether there is a Fibonacci number ≤ 1000 that is a multiple of
12(expected144).
The iterator version mirrors the behaviour of a generator; both yield the same sequence. Generators are usually more concise in Python, but iterators demonstrate how the protocol works under the hood.
Examples
Example 1
Input: top = 1000
Output: highest = 987, first_fib_multiple_of_12 = 144
Solution
Method 1 — Iterator class
Intuition
Maintain the two most recent Fibonacci numbers, a and b. Each step returns a and updates (a, b) = (b, a+b). Stop when a > top.
Approach
- Initialize
a = 0,b = 1, and storetop. - On each
next()/__next__()call:- If
a > topraiseStopIteration(or return a sentinel for languages without exceptions). - Store
result = a. - Update
a, b = b, a + b. - Return
result.
- If
Code
C++
class FibonacciIterator {
public:
FibonacciIterator(long long top) : top_(top), a_(0), b_(1) {}
bool hasNext() const { return a_ <= top_; }
long long next() {
long long r = a_;
auto nxt = a_ + b_;
a_ = b_;
b_ = nxt;
return r;
}
private:
long long top_, a_, b_;
};
Go
package main
type FibonacciIterator struct{ top, a, b int }
func NewFibonacciIterator(top int) *FibonacciIterator { return &FibonacciIterator{top:top, a:0, b:1} }
func (it *FibonacciIterator) Next() (int, bool) {
if it.a > it.top { return 0, false }
r := it.a
it.a, it.b = it.b, it.a+it.b
return r, true
}
Java
class FibonacciIterator implements java.util.Iterator<Long> {
private final long top;
private long a = 0, b = 1;
FibonacciIterator(long top) { this.top = top; }
public boolean hasNext() { return a <= top; }
public Long next() { long r = a; long nxt = a + b; a = b; b = nxt; return r; }
}
Kotlin
class FibonacciIterator(private val top: Long) : Iterator<Long> {
private var a = 0L
private var b = 1L
override fun hasNext() = a <= top
override fun next(): Long {
val r = a
val nxt = a + b
a = b; b = nxt
return r
}
}
Python
class FibonacciIterator:
def __init__(self, top: int):
self.top = top
def __iter__(self):
self.a = 0
self.b = 1
return self
def __next__(self) -> int:
if self.a > self.top:
raise StopIteration
result = self.a
self.a, self.b = self.b, self.a + self.b
return result
Rust
pub struct FibonacciIterator { top: u128, a: u128, b: u128 }
impl FibonacciIterator {
pub fn new(top: u128) -> Self { FibonacciIterator { top, a:0, b:1 } }
}
impl Iterator for FibonacciIterator {
type Item = u128;
fn next(&mut self) -> Option<u128> {
if self.a > self.top { return None }
let r = self.a;
let nxt = self.a + self.b;
self.a = self.b; self.b = nxt;
Some(r)
}
}
TypeScript
class FibonacciIterator {
top: number; a = 0; b = 1;
constructor(top: number) { this.top = top }
next(): { value: number, done: boolean } {
if (this.a > this.top) return { value: 0, done: true }
const r = this.a; [this.a, this.b] = [this.b, this.a + this.b]; return { value: r, done: false }
}
}
Complexity
- ⏰ Time complexity:
O(k)to generatekFibonacci numbers (each step constant time). - 🧺 Space complexity:
O(1)extra space (just a few integers to track state).
Method 2 — Generator / producer
Intuition
Generators produce the same sequence with less boilerplate. In Python use yield. In Go use a goroutine + channel. The generator approach is concise and clear.
Approach
- Start with
a = 0, b = 1andwhile a <= top:- yield
a - update
a, b = b, a + b
- yield
Code
C++
// adapter using FibonacciIterator
void generateFib(long long top, const std::function<void(long long)>& cb) {
FibonacciIterator it(top);
while (it.hasNext()) { cb(it.next()); }
}
Go
// channel-based generator implemented via FibonacciIterator
func FibGenerator(top int) <-chan int {
ch := make(chan int)
go func(){ it := NewFibonacciIterator(top); for { v, ok := it.Next(); if !ok { break }; ch <- v }; close(ch) }()
return ch
}
Java
// stream adapter using FibonacciIterator
import java.util.stream.Stream;
import java.util.Spliterators;
import java.util.stream.StreamSupport;
public static Stream<Long> fibStream(long top) {
FibonacciIterator it = new FibonacciIterator(top);
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, 0), false).takeWhile(v -> v <= top);
}
Kotlin
fun fibSequence(top: Long) = sequence {
val it = FibonacciIterator(top)
while (it.hasNext()) { yield(it.next()) }
}
Python
def fib_generator(top: int):
for v in FibonacciIterator(top):
yield v
Rust
// adapter returning the existing FibonacciIterator
fn fib_generator(top: u128) -> impl Iterator<Item = u128> {
FibonacciIterator::new(top)
}
TypeScript
// generator implemented using FibonacciIterator
function* fibGenerator(top: number) {
const it = new FibonacciIterator(top);
let res = it.next();
while (!res.done) { yield res.value; res = it.next() }
}
Complexity
- ⏰ Time complexity:
O(k)to produceknumbers. - 🧺 Space complexity:
O(1)per generator instance (plus any channel/iterator buffers in some languages).
Notes
- Use generators for concise code in languages that support them (Python, Kotlin, TypeScript). Use iterator classes when you need explicit control over state or to interoperate with APIs expecting an iterator object.
- Fibonacci numbers grow exponentially; the
k-th Fibonacci is ≈ phi^k / sqrt(5). The number of Fibonacci numbers ≤topisO(log top).