Design an iterator over a sequence with `hasNext()` and `next()`, then add a positive integer `step`. Make the API or object boundaries explicit, then cover invariants, edge cases, testing strategy, and operational trade-offs.
Design an iterator over a sequence with `hasNext()` and `next()`, then add a positive integer `step`.
For step `s`, each call to `next()` advances by `s` input elements and returns the element reached. For example, iterating `[1, 2, 3, 4, 5, 6]` with `step = 2` returns `2`, then `4`, then `6`. `hasNext()` reports whether another complete step can be made and must not advance the iterator.
### Constraints & Assumptions
- `step >= 1` is fixed when the iterator is created.
- Calling `next()` when `hasNext()` is false raises a defined exhaustion error.
- The source may itself be an iterator and therefore may not support indexing or rewinding.
### Clarifying Questions to Ask
- Should a partial final step return the last available element or count as exhausted?
- May `hasNext()` be called repeatedly without `next()`?
- Who owns and closes the underlying iterator?
```hint A generic source requires buffering
To answer `hasNext()` without losing elements, retain what you pull while looking ahead.
```
### What a Strong Answer Covers
- A precise cursor invariant and exhaustion contract.
- A simple indexed implementation and a buffered implementation for a one-pass source.
- Idempotent `hasNext()`, invalid-step handling, and boundary tests.
### Follow-up Questions
- How would you support changing the step between calls?
- What if the underlying iterator throws midway through a step?
- Can memory remain bounded by the step size?
Quick Answer: Design an iterator over a sequence with `hasNext()` and `next()`, then add a positive integer `step`. Make the API or object boundaries explicit, then cover invariants, edge cases, testing strategy, and operational trade-offs.
Design an iterator over a sequence with hasNext() and next(), then add a positive integer step.
For step s, each call to next() advances by s input elements and returns the element reached. For example, iterating [1, 2, 3, 4, 5, 6] with step = 2 returns 2, then 4, then 6. hasNext() reports whether another complete step can be made and must not advance the iterator.
Constraints & Assumptions
step >= 1
is fixed when the iterator is created.
Calling
next()
when
hasNext()
is false raises a defined exhaustion error.
The source may itself be an iterator and therefore may not support indexing or rewinding.
Clarifying Questions to Ask Guidance
Should a partial final step return the last available element or count as exhausted?
May
hasNext()
be called repeatedly without
next()
?
Who owns and closes the underlying iterator?
What a Strong Answer Covers Guidance
A precise cursor invariant and exhaustion contract.
A simple indexed implementation and a buffered implementation for a one-pass source.
Idempotent
hasNext()
, invalid-step handling, and boundary tests.
Follow-up Questions Guidance
How would you support changing the step between calls?
What if the underlying iterator throws midway through a step?