Why this is O(n)

Why O(n). It *looks* like there could be a nested operation, but len(out) is O(1) and out.append is amortised O(1). The single outer loop dominates.

Devious cousin. If the inner work were out.sort() (O(k log k) for k ≤ 3, so still O(1) here), or out.insert(0, s) (O(k), still O(1) because k ≤ 3), the analysis is the same. Bounded inner work doesn't change linear to quadratic.

How to recognize linear complexity in the wild

O(n) is one pass over the input. The strongest signal is a single for-loop that touches every element exactly once, or a recursion whose depth equals the input size with constant work per level.

The eight rungs of the ladder

Big-O classifies the asymptotic growth of a function, not the wall-clock time. The ladder Bugdle uses has eight rungs ordered from cheapest to most ruinous: O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!). The puzzle's answer sits at rung 3 of 8. The four-guess budget plus higher/lower hints means the puzzle is solvable in at most ⌈log₂(8)⌉ = 3 perfectly-read guesses; the fourth attempt absorbs misreads of the snippet.

Common confusables

Nested loops aren't automatically quadratic — the inner loop has to range over n, not a constant. A loop that always runs ten iterations is still O(1) work per outer iteration. Similarly, a recursive function isn't automatically exponential just because it calls itself twice — if the recursion has overlapping subproblems and you memoise, you collapse back to polynomial. Always ask: what does n really mean here, and how many distinct subproblems are there?

External reference: Big O notation — Wikipedia.