befunge

Why does the Befunge code 9332682811>\#+:#*9-#\_$.@ output 52256370?


Today I tried to make an account on Esolangs.org, the esoteric programming languages wiki. I'd contributed to a few wikis before, and I had one or two minor page edits I wanted to contribute.

...that is, until I saw the CAPTCHA verification puzzle used to create a new account.

Captcha puzzle for Esolangs.org

Using an obscure language for the CAPTCHA was most likely intended as a silly in-joke. However, I spent nearly half an hour trying to understand the language so I could create a new account.

Eventually I gave up and used an online Befunge interpreter, which gave me the answer 52256370.

What I don't understand is why the output of 9332682811>\#+:#*9-#\_$.@ is 52256370.

I've seen a few comments suggesting it's a conversion from base-10 to base-9. However, when I tried to verify by converting 9332682811 with an online base converter, I got a result of 26072072027.


Solution

  • This program parses 332682811 as a little-endian base-9 integer and prints it in base-10.

    Befunge interprets instructions on a 2D grid (or torus, depending on version), with an instruction pointer that can move freely in two dimensions. This program is a one-liner, so the instruction pointer only moves forward and backward.

    9332682811 pushes those digits individually onto Befunge's value stack, and then the following instructions perform a simple loop. In a normal iteration of the loop, things look like this:

    Instructions              Meaning                                       Top stack values
    
    9332682811>\#+:#*9-#\_$.@
              >               Set the instruction pointer to travel         a b
                              to the right.
               \              Swap the top 2 values on the stack.           b a
                #+            Nothing, since # means                        b a
                              skip the next instruction.
                  :           Duplicate the top value on the stack.         b a a
                     9        Push 9.                                       b a a 9
                      -       Pop two values and push their difference.     b a (a-9)
                         _    Pop the top value and set the instruction     b a
                              pointer traveling right if the value is 0
                              or left otherwise.
                        \     Swap the top 2 values.                        a b
                     9        Push 9.                                       a b 9
                    *         Pop two values and push their product.        a (b*9)
                 +            Pop two values and push their sum.            (b*9 + a)
              >               Set the instruction pointer traveling
                              right again.
    

    So unless the second value on the stack at the start of an iteration is 9, the iteration pops two values b and a and pushes b*9 + a.

    If the second value is 9, the loop terminates and prints the top value:

    Instructions              Meaning                                       Top stack values
    
    9332682811>\#+:#*9-#\_$.@
                         _    Pop the top value and set the instruction     b a
                              pointer traveling right if the value is 0
                              or left otherwise.
                          $   Discard the top value.                        b
                           .  Pop and print the top value.
                            @
    

    So, in summary, the program pushes a bunch of digits and repeatedly replaces a and b with b*9+a until it hits 9, the signal to stop. This is a base 9 converter.

    If you try to verify this with another base converter, make sure you get the endianness right. 332682811 is little-endian, so you may need to reverse it.