CognitoCoding All posts
3 July 2026 3 min read by Eris Taylor

I Wrote a Bubble Sort to Harvest Cactus — And Then It Crashed at the Boundary

pythonthe-farmer-was-replacedlearn-to-codesorting-algorithmsbeginners

Nobody sits down and decides to learn bubble sort.

Usually something forces the issue. In Episode 6 of I Taught an AI to Farm, that something was a cactus field — and a drone that needed to figure out which plants were ready to harvest in the right order.

The problem the cactus revealed

In earlier episodes, the drone could harvest in any order. Wheat doesn't care when you collect it. Pumpkins rot if you ignore them, but the fix was simple: check every square and harvest the ripe ones.

Cactus is different.

Cactus grows in stages. If you harvest a plant that's still growing, you lose yield. If you harvest the tallest plant first when shorter ones are blocking the path, you trap yourself. The drone needed to sort the cactus by height before deciding what to harvest — shortest accessible ones first, leaving the tallest for a second pass.

That's a sorting problem in disguise. And the simplest sorting algorithm that could solve it is a bubble sort.

What a bubble sort actually does

Bubble sort works by going through a list, comparing two items at a time, and swapping them if they're in the wrong order. Then it goes through the whole list again. And again. Until it makes one complete pass without swapping anything — at which point the list is sorted.

The name comes from how the larger values gradually "bubble" to the end of the list as you keep comparing pairs.

Here's what it looks like in Python:

def bubble_sort(heights):
    n = len(heights)
    for i in range(n):
        for j in range(0, n - i - 1):
            if heights[j] > heights[j + 1]:
                heights[j], heights[j + 1] = heights[j + 1], heights[j]
    return heights

Two loops. The outer one tracks how many passes you've done. The inner one does the actual comparing and swapping.

After each pass, the largest unsorted value has "bubbled" to its final position — which is why the inner loop shrinks by one each time (n - i - 1). You don't need to re-check positions that are already sorted.

The boundary crash

The bubble sort worked. The cactus got sorted. But then the drone crashed.

Not a dramatic crash — just an index error. The drone was trying to access position j + 1 when j was already pointing at the last item in the list.

In Python, if your list has 5 items (positions 0 to 4) and you try to access position 5, you get:

IndexError: list index out of range

This is called a boundary error — sometimes called an off-by-one error. You went one step past the end of the list.

The fix is the n - i - 1 part in the inner loop. It stops the comparison one step before the end, so j + 1 never points somewhere that doesn't exist. Without it, the loop runs all the way to the last item, then tries to look one step further — and crashes.

What the fix revealed

Adding n - i - 1 wasn't just a patch. It's the reason bubble sort works correctly at all.

Without the guard:

  • The algorithm crashes on the final comparison of every pass
  • Even if it didn't crash, it would be doing unnecessary work on positions that are already in their final place

Boundary conditions are one of the most common sources of bugs in any loop-based code. The rule is simple: whenever you're comparing or accessing thing[index + 1], ask what happens when index is the last position in the list. If the answer is "it crashes" — you need a guard.

Why this matters beyond cactus farming

Bubble sort isn't the fastest algorithm in the world. For large lists there are much better options. But it's worth understanding because:

  • It makes the logic of "compare and swap" completely visible — no hidden steps
  • The boundary bug it reveals is one you'll hit in every language, in every kind of list processing
  • It's a stepping stone to understanding faster sorts (merge sort, quick sort) that use the same core idea but smarter strategies

The drone's cactus problem wasn't a textbook exercise. It was a real constraint the game imposed, and the sorting logic had to actually work to move on. That's what makes it stick.

Watch Episode 6 here: I Taught an AI to Farm Ep 6