What general tips do you have for golfing in Befunge? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to Befunge (e.g. "remove comments" is not an answer). Please post one tip per answer.
Need to drop a value after a conditional (e.g. because the other path depends on the value, but this one doesn't)? Instead of using
$<, take advatage of the fact that you know the truth value of the variable and use
_ instead to both change direction and pop stack.
'* : v >$ .. @ Prints number in binary followed by the original decimal number. > :2%\2/ :!#^_ \.
gets turned into
'* : v _ .. @ Since we know that the topmost value on the stack will be 0, we combine `>$` into `_`. > :2%\2/ :!#^_ \.
Instead of using
|, requiring another line (often with many extra spaces), try using
j. For example:
01-`j@more code here
would stop if the number on top of the stack was negative and continue onward otherwise. If you need multiple characters, use
n is the number of characters you need when the value passed to
which would negate a negative number.
In Befunge-93, if the first thing you're pushing onto the stack is a string, you can often get away with dropping the opening quote. For example this:
could be simplified to this:
What's happening is the interpreter first tries to execute the characters in the unquoted string. The
! performs a harmless not, and the
H are not valid instructions, so they're ignored (although on some implementations you may get a warning).
" is encountered, that is considered the start of the string, but because there is no closing quote, it wraps all the way around the playfield until the
" is encountered a second time. What ends up pushed onto the stack is then this:
,,,@ ···72 spaces··· !iH
Since we only care about the last few characters, though, none of that other stuff matters. So after the quote, we then finally get to execute the three
, commands, writing out the message, and the
@ command, which exits.
Note that this won't typically work in Befunge-98, since an unrecognised instruction will cause the interpreter to reflect instead of ignoring it.
In Befunge-93, the character input command (
~) can often be used as a shortcut for -1, since that is the value it returns on EOF.
As an example, the code below will output -1:
This is not recommended in production code, since when run in an interactive environment, the program would pause and wait for user input. And obviously if the user were to input something, the result would no longer be -1.
Also note that you aren't necessarily precluded from using this trick just because your program needs to read something from the input stream. You just have to make sure you process your inputs up front, after which all future uses of
~ should return -1.
In Befunge-93, it can often be advantageous to flatten a loop into a single line, with the loop section of code being executed in both directions.
For example, consider the code below, which outputs the letter
a eight times:
This can flatten be flattened into a single line by interspersing the loop sequence with bridge instructions (
If you're just looking at the non-whitespace characters, you may get the impression that this is longer than the the original. But once you take into account the linefeed and the additional padding required in the two line version, you actually end up saving four bytes.
In this particular case, the code be compressed even further by noting that that sequence
:#: can simply be replaced with
In fact, any time you have the same instruction repeated on either side of a
# command, you can simplify that to just the one instruction, so this is something you should always be looking out for when flattening a loop.
To understand how this works, it can help to write out the loop sequence twice, once with all the characters following the
# removed (i.e. what happens when executing left to right), and once with the characters preceding the
# removed (i.e. executing right to left).
"a"9>1#\-#,:>#\_@ >1 - :> _ ; executing left to right > \ ,: \_ ; executing right to left
You can clearly see now how this matches the original two line version of the code.
Use the direction of the IP when dealing with
|, rather than using an extra character for
Real example (from this post):
Can be changed to
When pushing small numbers onto the stack, you can probably figure out easily enough that
45* will get you
67* will get you
42. When it comes to larger numbers, though, you really need a program that can calculate the most efficient representation for you.
The easiest option for this is Mike Schwörer's online interface for BefunRep. You simply type in a number and it'll spit out an equivalent Befunge representation. It's not always the most optimal, but it's close enough, and it's almost certain to be better than anything you could come up with by hand.
The online system is limited to numbers in the range 0 to 16777215, so if you need anything larger than that, you'll want to download the standalone BefunRep utility and run the calculations yourself.
If you're programming in Befunge-98, another option to consider is Fungify. In general it isn't nearly as optimal as BefunRep, but for some of the lower numbers, where hex digits and single quote characters are most effective, it can sometimes produce better results.
Merge branches as soon as possible
If two or more code branches are merging together and they all end with the same sequence of instructions, you can merge them immediately before the instructions they have in common. This is a fairly common circumstance to be on the lookout for.
As an example, I have this subprogram for reading input onto the playing field from my self-interpreter:
Notice that three different branches are coming together at the marked cell, each of which wants to write to the playing field. The one on the top right is
520p to put 5 at (2,0). The top left is
00p to put the computed value at (0,0). And on the right (and below) is
20p to put the computed value at (2,0). Since all of these instructions end with
0p, I save at least 4 bytes by merging the branches first and then doing
Use String Mode to Allow the IP to Pass Through Other Code
If you need the IP to get from here to there and there's a bunch of existing and unmovable code in the way in every direction, just push a 0, go into string mode, pass through the code, come out of string mode, and pop all the garbage before continuing. This trick employed in Wim Rijnder's Wumpus here:
(Yes, it would have been more efficient to put the quotes closer to the actual code there, but this is golf--we don't care about speed!)
This trick requires you to be able to spare at most 2 cells on this side and at least 3 on the other side, but it might end up saving space in the long run if writing yourself into a corner that requires this trick ends up greatly compressing the rest of the program. (In particular it could save you from having to write in a low-code-density "lane" for the IP to travel down.)