Writing

Solving a problem before I run any code

3 Nov 2026, 3 min read

I recently solved a problem without running a single line of code until the end. Not because I’m fast. It’s because of a routine I follow every time:

  1. 1ReadThe whole problem, constraints included.
  2. 2RedrawIn my own words. If I can’t explain it simply, I don’t get it yet.
  3. 3Trace by handOne small example. Every variable, every step.
  4. 4Open the editorOnly now. The code is the easy part.

For that problem, the trace showed me something I would have missed in code: which parameter was a reference and which was a copy. That was half the answer.

Why it matters in Swift

Swift makes the difference between value and reference types very real.

That changes how recursion behaves. Take backtracking, where you build a path and undo choices:

func subsets(_ nums: [Int]) -> [[Int]] {
    var result: [[Int]] = []

    func explore(_ index: Int, _ path: [Int]) {
        if index == nums.count {
            result.append(path)
            return
        }
        explore(index + 1, path + [nums[index]])  // choose
        explore(index + 1, path)                  // skip
    }

    explore(0, [])
    return result
}

Because path is a value, each call gets its own version. There’s no “un-choose” step, since nothing is shared.

Now make the path a reference, or pass it inout, and the rules change:

func explore(_ index: Int, _ path: inout [Int]) {
    if index == nums.count {
        result.append(path)
        return
    }
    path.append(nums[index])   // choose
    explore(index + 1, &path)
    path.removeLast()          // un-choose — now required
    explore(index + 1, &path)
}

Forget removeLast() here and every branch sees the leftovers of the branches before it. The output is wrong, and nothing crashes.

What tracing catches

When I trace by hand, I draw each variable as a box. Value types get a new box for every call. References get an arrow pointing to one shared box. The moment two arrows point at the same box, I know mutation will leak between calls, and I know whether I need an undo step.

That’s the whole point of tracing first. Writing the code is the easy part once the model in my head matches what the program actually does.