Befunge Techniques

A Worked Countdown Program

Follow a two-row Befunge countdown from 9 to 1 one step at a time, with the stack contents and pointer direction written out at every instruction.

On this page
  1. The program
  2. First pass, cell by cell
  3. The return trip
  4. The last pass
  5. Why the duplicate matters
  6. Why the order of operations is what it is
  7. What to take from it

The program

Here is a complete Befunge-93 program that prints the numbers from 9 down to 1. It is two rows long.

9>:.1-:#v_@
 ^      <

Row 0 is 9>:.1-:#v_@ and row 1 is a space, a ^, six more spaces and a <. The pointer starts at the top-left cell moving east. Each . prints a number followed by a space, so the output is 9 8 7 6 5 4 3 2 1 with a trailing space.

Write the columns out so you can refer to them. In row 0, column 0 is 9, column 1 is >, column 2 is :, column 3 is ., column 4 is 1, column 5 is -, column 6 is :, column 7 is #, column 8 is v, column 9 is _ and column 10 is @. In row 1, column 1 holds ^ and column 8 holds <, directly beneath the v.

First pass, cell by cell

The stack is shown with the top on the right.

Cell Instruction What it does Stack after
(0,0) 9 push 9 9
(1,0) > move east 9
(2,0) : duplicate the top 9 9
(3,0) . pop and print 9 9
(4,0) 1 push 1 9 1
(5,0) - pop 1 and 9, push 9 minus 1 8
(6,0) : duplicate 8 8
(7,0) # skip the next cell 8 8
(9,0) _ pop 8; nonzero, so go west 8

Notice that cell (8,0), the v, was skipped on the way east. The # jumped over it, so the pointer landed directly on _. That is the job of the trampoline instruction: the v is only meant to be used when the pointer comes back from the other side.

Subtraction deserves a second look. The - instruction pops the top value first, then the value beneath it, and pushes the second minus the first. With 9 and then 1 pushed, the result is 9 minus 1, which is 8. Pushing them the other way around would give a different answer.

The return trip

Because _ found a nonzero value, it sends the pointer west. The pointer moves from column 9 to column 8 and now lands on the v that it skipped before. Arriving from the east, v turns the pointer downward, so it enters row 1 at column 8.

The < in row 1 sits in the same column as the v, so the pointer arrives on it moving down, turns west and slides along the empty cells of row 1 until it reaches the ^ in column 1. That turns it north, up into the > at (1,0), which sends it east again. The loop is a plain rectangle.

The stack on the return trip is untouched, since none of those cells do anything except steer. The next pass begins with 8 on the stack: duplicate, print 8, subtract to get 7, duplicate, skip, test, and so on.

The last pass

Skip ahead to the iteration that prints 1. Before it, the stack holds 1. The steps are:

  1. : makes it 1 1.
  2. . prints 1, leaving 1.
  3. 1 pushes another 1, giving 1 1.
  4. - subtracts, leaving 0.
  5. : duplicates, giving 0 0.
  6. # skips the v.
  7. _ pops a 0, which means go east.

The pointer then moves east into the @ at the end of row 0 and the program stops. A single 0 remains on the stack, which does no harm. Most interpreters do not care about leftovers when the program ends, though tidy code often removes them with $.

Why the duplicate matters

The test needs a value to examine, but _ consumes whatever it examines. Without the second :, the counter itself would be popped by the test and the next pass would have nothing to print. Duplicating just before the test is the standard remedy, and it is a pattern you will see in almost every loop. Forgetting it is one of the most common beginner mistakes, and it usually shows up as a stack underflow or as a loop that ends after one pass.

Why the order of operations is what it is

Printing before subtracting means the program prints 9 first and never prints 0. If you want the zero too, test before you decrement instead, or change the exit condition so the loop continues one step longer. Either change is a small edit, and trying it is a good exercise in tracing by hand.

You can also experiment with the starting value. Replace the 9 with another single digit and the same program counts down from that digit. The loop does not care how many times it runs, only that the counter eventually reaches zero. For larger starting values you would build the number with arithmetic, for example by multiplying two digits, because only digits 0 to 9 can be pushed directly.

What to take from it

Three ideas in this small program recur everywhere. First, duplicate a value before testing it. Second, let one test cell serve a loop by using a skip to choose which way it is approached. Third, route the return path as a clean rectangle so the loop can be read at a glance. The guide on writing loops generalizes these ideas, and the page on the Befunge language itself describes the grid and pointer that make them possible.

The complete guide to befunge techniques

Befunge Programming Techniques Overview
Read the guide

Keep exploring

Guides from other topics

All topics →