Puzzle Practice

FizzBuzz in Odd Languages

A look at the classic FizzBuzz puzzle and what changes when you express it in a tape, stack or grid language instead of a conventional one.

On this page
  1. The exercise
  2. A reference version
  3. The pieces every language must supply
  4. On a tape
  5. On a stack
  6. On a grid
  7. What the comparison teaches
  8. Try it yourself

The exercise

FizzBuzz is a small, well-known exercise. Count from 1 to 100. For each number, print “Fizz” if it is divisible by 3, “Buzz” if it is divisible by 5, “FizzBuzz” if it is divisible by both, and otherwise print the number itself.

The exercise is popular because it is short but touches several basic ideas at once: a loop, a remainder operation, branching, and output that mixes text and numbers. That makes it a convenient way to compare languages. If you can see how a language handles each of those four pieces, you learn a lot about how it thinks.

A reference version

Here is a version in Python, which will serve as the baseline:

for n in range(1, 101):
    if n % 15 == 0:
        print("FizzBuzz")
    elif n % 3 == 0:
        print("Fizz")
    elif n % 5 == 0:
        print("Buzz")
    else:
        print(n)

Testing for divisibility by 15 first works because a number divisible by both 3 and 5 is divisible by 15. Another common approach builds the output as a string: start with an empty string, append “Fizz” if divisible by 3, append “Buzz” if divisible by 5, and print the number only if the string is still empty. That version generalizes more easily to extra rules, which is worth remembering because odd languages sometimes make one style much cheaper than the other.

The pieces every language must supply

Break the exercise into its parts and ask how a language can provide each one:

  • Counting. Something has to hold the current number and increase it.
  • Remainders. Most languages have a modulo operation. Some have only addition and subtraction, in which case you repeatedly subtract or keep a second counter that wraps around.
  • Choosing. Branching can be an if statement, a conditional jump, a direction change, or something stranger.
  • Output. Printing words is easy in some languages and laborious in others, where each character must be produced as a number. Printing a multi-digit number often needs extra work, as the topic of base conversion shows.

On a tape

In Brainfuck commands, there is no modulo and no comparison. Every memory cell holds a number, and you can only increment, decrement, move left or right, loop while a cell is nonzero, and read or write characters. A FizzBuzz here is possible but long. A common approach avoids division altogether by keeping two small counters that count down from 3 and from 5 and reset when they reach zero. When the first reaches zero it is time for “Fizz”; when the second does, “Buzz”. Printing the decimal number requires splitting it into digits yourself.

The result is a good illustration of how a language with few operations pushes you toward counters rather than arithmetic. It also shows why Brainfuck patterns, such as copying a value using a temporary cell, come up repeatedly.

On a stack

Stack languages keep values in a pile and operate on the top. Modulo is usually available, so the logic is closer to the reference version. The challenge is data juggling: to test a number against both 3 and 5 you need to duplicate it, and you have to keep the original around to print. Programs end up as a sequence of small stack manipulations, and tracking what is on the stack at each point is the main difficulty. Careless handling can lead to stack underflow when an operation finds fewer values than it expected.

On a grid

In a grid language like Befunge, the same logic is expressed as paths. The loop is a circuit the pointer travels around. The divisibility test is a branch where the pointer turns up or down depending on the remainder, which is exactly what conditional branching with the horizontal and vertical if provides. Text is pushed with string mode and printed by a small output loop.

A typical layout dedicates one lane to the “Fizz” check, another to the “Buzz” check, and a merge point where the number is printed if neither fired. Because you can see the structure, a grid FizzBuzz is often easier to follow visually than a tape one, though the code can take a surprising amount of space. Getting the paths to line up without crossing by accident is a puzzle of its own, and good code layout makes the difference between a readable program and a tangle.

What the comparison teaches

Working through the same exercise in different models highlights a few ideas:

  • Operations you take for granted are choices. Modulo is convenient, not fundamental. Replacing it with counters is a standard trick.
  • Data and control are shaped by the model. On a tape you move to the data; on a stack the data comes to you; on a grid the control flow itself is drawn.
  • Output formatting matters. In conventional languages printing is a single call. In others it takes up most of the program.
  • Different styles have different costs. The string-building approach may be cheap in one language and expensive in another.

Try it yourself

A gentle way to approach this is to start with a smaller problem, such as printing “Fizz” for every third number up to 15, and add one rule at a time. Trace each version on paper for the first few values before running it. If you want to compete, a short version of FizzBuzz is a classic code golf target, and the shortest solutions often rely on language-specific tricks you would not use in everyday code.

FizzBuzz is not special beyond being familiar, but that familiarity is the point: when you already know what the program should do, you can focus on how the language lets you say it.

The complete guide to puzzle practice

Puzzle Programming Practice
Read the guide

Keep exploring

Guides from other topics

All topics →