Hello World in Multiple Languages

16 languages, 1363 bytes

 #define ip"MemuL tulaS",,,,,,,,,,"!",@++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.@,kc"Kaixo Mundua!"v#!
#define print(A,B,C)main(){printf("Helo Byd!");}//ss                                                                          ;ooooooooooooooooooo"Moni Dziko Lapansi!"<  
#ifdef __cplusplus//p                                                                                                                                 ;;];;
#define print(A,B,C)int main(){printf("Halo Dunya!");}//ssp
#endif//;  [;;;;;;;;;     "!etejivs vardzoP"]
#ifdef __OBJC__//;;;;;
#define print(A,B,C)main(){printf("Hallo Welt!");}//ss
"""echo" "Salom Dunyo!";"exit";puts"Moien Welt!";\
#define B//\
print(["Hai dunia!","Hej Verden!","Halo Dunia!"][(int(1>0)is 1)+~int(-1/2)*2])
#define s eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeejeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeejiiiiiiiijeeeeeeeeeeeeeejiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiijeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeejeejijiiiiiiiiiijeeeeeeeeeeejiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiij
#define U   !"!dlereW ollaH"<           ;
#define T@,kc"Sannu Duniya!?%?"

Try it online!

(use "switch languages" to change language)

  • Python 3 = Halo Dunia! (Indonesian)

  • Python 2 = Hej Verden! (Danish)

  • Python 1 = Hai dunia! (Malay)

  • C (gcc) = Helo Byd! (Welsh)

  • C++ (gcc) = Halo Dunya! (Sundanese)

  • Objective C (clang) = Hallo Welt! (German)

  • Brainfuck = Hello World! (English, obviously)

  • Befunge-93 = Salut Lume! (Romanian)

  • Ruby = Moien Welt! (Luxemburgish)

  • Bash = Salom Dunyo! (Uzbek)

  • Befunge-98 (PyFunge) = Kaixo Mundua! (Basque)

  • Unefunge-98 (PyFunge) = Sannu Duniya! (Hausa)

  • Cardinal = Hallo Wereld! (Dutch)

  • Alphuck = Ciao mondo! (Italian)

  • ><> = Moni Dziko Lapansi! (Chichewa)

  • Fission = Pozdrav svijete! (Croatian)

Any golfing tips are welcome (especially on the Brainfuck)!!

Thanks to @JonathanFrech for -1 byte! Also, thanks to @ovs for -40 bytes!

How (general ideas, I actually forgot specifics)??

The languages can be put into four groups:

  • Macro: C, C++, Objective C
  • Comment: Python3, Python2, Python1, Ruby, Bash
  • Dimensional: Befunge-93, Befunge-98, Unefunge-98, Cardinal, ><>, Fission
  • Vulgar: Brainfuck, Alphuck

The Macro languages see # as the start of a preprocessor directive. These are used for three reasons: to house code for other groups, to distinguish among Macro languages, and to actually define a macro. All three use // as comment, so after that we store code for the other groups. Also, the backslash continues the comment in these languages.

The Comment languages see # as the start of a comment. The quirk here is the triple quotes, which distinguish the Pythons from Ruby from Bash. And to distinguish Python 1 from 2 from 3, we use a distinguishing feature in all three, along with an array of outputs. Oh yeah, there's also that __END__. This is used to end the code for some (can't remember exactly which ones) of the Comment languages.

The Dimensional languages are distinguished in a way that is hard to explain. One has to know the specifics of each language to figure it out. For example, # is only a skip in the fungeoids, while it does various different things in the other languages. The code is strewn about everywhere for these languages.

And finally, we arrive at the Vulgar languages. These two ignore everything that isn't in their set of valid characters. A balancing act has to be played with these languages and the others, as the code already contains characters in the character sets.

15 languages, 532 bytes

# ;"!audnuM oxiaK">:#,_@R"Hej Verden!";;@,kb"Tere maailm!";# w"!amliaam ieH"ck,@oooooooooo"Hai dunia!"
`true #{puts'Hola món!'}` \
"Hola Mundo!" puts
case `ps -p$$ -oargs=` in \
b*)echo Hallo Welt!;;k*)echo Ndewo Ụwa!;;d*)echo Ciao mondo!;;z*)echo Moien Welt!;;a*)echo Hei Verden!;;esac
#x%"Olá Mundo!"x

Try it online!

  1. Kaixo Mundua! in Befunge-93
  2. Hej Verden! in Fission
  3. Tere maailm! in Unefunge-98
  4. Hei maailma!! in Befunge-98
  5. Hai dunia! in ><>
  6. Hola món! in Ruby
  7. Hola Mundo! in GolfScript
  8. Hallo Welt! in bash
  9. Ndewo Ụwa! in ksh
  10. Ciao mondo! in dash
  11. Moien Welt! in zsh
  12. Hei Verden! in ash
  13. Olá Mundo! in Cardinal
  14. Hello World! in brainfuck, courtesy of primo.
  15. Helo Byd! in Whitespace


Line 1 distinguishes between five 2D esolangs:

  1. ><> reads # as a mirror, wraps around to the left, prints "Hai dunia!" and crashes (@). All the Funges read it as a trampoline and go right.
  2. Befunge-93 ignores ;, prints Kaixo Mundua! and exits (@).
  3. The ’98 Funges jump from the first ; to the second, then from the third ; to the fourth. w is a NOP for Befunge-98, printing Hei maailma!.
  4. But w reflects the instruction pointer in Unefunge-98, printing Tere maailm!.
  5. Fission doesn’t start in the top-left corner at all. R"Hej Verden!"; is executed. (Another instruction pointer starts from the D in __END__, but it does nothing then dies to the ; in true;.)

Ruby sees `true #{puts'Hola món!'}`, then __END__.

GolfScript sees `, then true (NOP), then a comment; then __END__ (NOP); then "Hola Mundo!" puts (this is executed); then case (NOP), then ` (crashes on empty stack).

The shells see a comment, then an invocation to true (NOP), then invocations to unknown commands __END__ and "Hola Mundo!" (which error to STDERR but execution continues), then the case statement which distinguishes based on the first letter of the name of the current process.

Cardinal is another 2D esolang which starts at the %, sending 4 IPs up, down, left, and right. They're all killed by the surrounding x commands, but one prints "Olá Mundo!" before dying.

The brainfuck code is primo’s, prefixed with ++ to counteract the dashes in ps -p$$ -oargs=.

The whitespace in my code is executed as the Whitespace program

 push 0
 push 0
 push 0
 push 0
 push 72; printc
 push 101; printc
 push 108; printc
 push 111; printc
 push 32; printc
 push 66; printc
 push 121; printc
 push 100; printc
 push 33; printc

which prints Helo Byd!

EDIT: I forgot that adding UDLR characters breaks the Fission program, so I’ve changed the strings up to avoid these.

23 Befunges, 713 bytes

The only language I really know is Befunge, so instead of multiple languages, I've just gone with multiple implementations of Befunge. I believe this is still valid under PPCG rules, which consider the language to be defined by its implementation.

8023/# !-1401p680p88+79*6+1p238*7+0pg90p$#v0';1';+>9%80p$$$$"ph~s"+3vv
vv_2#!>#-/\#21#:+#:>#\<0/-2*3`0:-/2g01g00p>#< 2#0 ^#1/4*:*9"9"p00***<<
       !Helo Byd!!!!!Hai dunia!!!!Ciao mondo!!!Hallo Wereld!!!!
       !Hallo Welt!!!Halo Dunia!!!Halo Dunya!!!Bonjour monde!!!
       !Hei Verden!!!Hej Verden!!!Moien Welt!!!Labas pasauli!!!
       !Molo Lizwe!!!Salut Lume!!!Hei maailma!!Sveika pasaule!!
       !Hello World!!Salom Dunyo!!Tere maailm!!Sawubona Mhlaba!
       !Kaixo Mundua!Salamu Dunia!Sannu Duniya!!!!!!!!!!!!!!!!!

The frustrating thing about Befunge, is that although there is an open source reference implementation, and the language itself is dead simple, there isn't a single third-party interpreter (that I'm aware of) that exactly matches the reference behaviour. Every implementation fails in a different way.

On the plus side, this gives us the opportunity to develop a single piece of code that will produce a different result in almost every interpreter. And that's what I'm attempting in the program above.

If anyone is interested in verifying the results, I've tried to group the various implementations into categories based on how easy they are to get up and running (e.g. some people may not be able to run Windows binaries, or may not be willing to build from source, but everyone should be able to test the online interpreters).

Online Interpreters

No installation required. It's usually just a matter of pasting in the code and clicking a button or two. But note that some of these are quite slow, so may need some time to finish executing.

Alexios' Befunge Playground - Salamu Dunia!

Click the Clear... button and paste the code into the input field. Toggle the Edit switch to activate the interpreter, and then click the Run button to begin executing.
Note that this site probably won't work in Browser's other than Chrome.

Befungius - Molo Lizwe!

Paste the code into the input field, making sure to overwrite the existing code. Then click the Run button to execute.

David Klick's Befunge 93 Interpreter - Sannu Duniya!

Paste the code into the Playfield input field, and then click the Run button to begin executing.

Ian Osgood's Befunge-93 Interpreter - Salut Lume!

Paste the code into the input field under the Show button, making sure to overwrite the @ that is already there. Click the Show button to import the code, then click the Run button to begin executing.

jsFunge IDE - Hej Verden!

First close the Help dialog, then click the Open/Import toolbar button (second from left), paste in the code, and click OK. To execute, click the Run Mode button (fourth from left), and then Start (fifth from left).

Also note that a few of the console-based interpreters are actually available on TIO, so while they aren't technically online interpreters, they can be tested online. For those that are supported (currently BEF, FBBI, MTFI and PyFunge), I've included a Try It Online! link next to their entry.

Java IDEs

You'll need to have the Java run-time installed for these, but they should theoretically work on any platform. Only tested on Windows though.

Ashley Mills' Visual Befunge Applet - Moien Welt!

This was initially an online applet which is unfortunately no longer available, but you can still download the jar and run it locally as a desktop application. You'll need to paste the code into the Program Editor window, then click the Convert button, followed by the Run button.

WASABI: Wasabi's A Superbly Asinine Befunge Interpreter - Hallo Welt!

To paste in the code, right click in the top left corner of the editor window (it must be the very top left) and select the Paste menu item. Then enable the Full Speed check box (otherwise it'll take forever), and click the Run! button to begin executing.

YABI93: Yet Another Befunge93 Interpreter - Halo Dunia!

Press Ctrl+A, Ctrl+V to paste the code into the editor window, being sure to overwrite the default source. Then click the Start button to begin executing.

Windows IDEs

You'll typically need Windows for these, although in some cases there may be binaries available for other operating systems. I can't promise the code will work on other platforms though.

BefunExec - Hello World!

You can't paste the code into the editor, so you'll first need to save it to disk somewhere. Then from the IDE, use the File > Open menu to load the code from disk, and select the Simulation > Run/Pause menu to run it.

BeQunge - Labas pasauli!

Press Ctrl+V to paste in the code, and then click the Debug toolbar button (the blue cog) to begin executing. Once the Debugger panel appears, you'll want to set the Speed to maximum - the button to the right of the slider - otherwise it'll take forever to finish.

Fungus - Tere maailm!

Press Ctrl+V to paste in the code, and then press F5 to run it.

Visbef: Visual Befunge '93 for Windows - Hallo Wereld!

You can't paste the code into the editor, so you'll first need to save it to disk somewhere. Then from the IDE, press Ctrl+O to open the file browser and load the code from disk, and press F5 to run it.

Windows Console Apps

Again these typically require Windows, although other platforms may be available, but not guaranteed to work.

In all cases the code will need to be saved to a file on disk and the filename passed to the interpreter as a command line parameter (source.bf in the example command lines given below). Also note that some of these are technically Befunge-98 interpreters, and must be run with a particular command-line option to force a Befunge-93 compatibility mode. If you don't do that, you won't get the correct results.

BEFI: Rugxulo's Befunge-93 Interpreter - Hei Verden!

Command line: bef93w32 -q source.bf

CCBI: Conforming Concurrent Befunge-98 Interpreter - Sveika pasaule!

Comand line: ccbi --befunge93 source.bf

MTFI: Magus Technica Funge Interpreter - Hai dunia!

Command line: mtfi -3 source.bf (Try it online!)

Python and PHP Console Apps

These require the appropriate scripting language installed - either Python or PHP.

Befungee - Helo Byd!

Command line: befungee.py source.bf

PyFunge - Halo Dunya!

Command line: pyfunge -v 93 source.bf (Try it online!)

Bephunge - Bonjour monde!

Command line: php bephunge.phps source.bf

Source-only Console Apps

These will need to be built from source, and that's usually easiest with a *nix-like environment. On Windows I use the Windows Subsystem for Linux.

BEF: Befunge-93 Reference Distribution - Ciao mondo!

Command line: bef -q source.bf (Try it online!)

cfunge - Sawubona Mhlaba!

Command line: cfunge -s 93 source.bf

FBBI: Flaming Bovine Befunge-98 Intepreter - Hei maailma!

Command line: fbbi -93 source.bf (Try it online!)

Fungi - Kaixo Mundua!

Command line: fungi source.bf

Rc/Funge-98 - Salom Dunyo!

Command line: rcfunge -93 source.bf

How it works

The challenge with this was finding the fewest number of tests that provided the most differentiation between interpreters. In the end it came down to four main test sequences:

  1. The first is an out-of-bounds memory read from offset -1,1. In theory this should always return 32 (ASCII space), but there were actually 10 variations in practice. This test is complicated by the fact that two of the interpreters crash on an out-of-bounds read, so a couple of special-case tests (division rounding and space bridging) were required to force those two back into bounds.

  2. The second sequence is a test of Befunge-98 functionality - specifically the instructions ; and '. Almost all of the interpreters are Befunge-93, or are run in Befunge-93 compatibility mode, so they should just ignore those instructions. In practice there were 6 different ways in which this sequence was interpreted.

  3. The third test checks the range of memory cells. In the reference interpreter, memory cells are signed 8-bit, but other implementations vary in range from 8-bit to unbounded, some signed and some unsigned. However, for the purposes of this test, we only had to distinguish between 5 of those variants.

  4. The fourth and final sequence is a combination of underflow and negative division tests. There are a number of ways in which interpreters get underflow wrong, and there are at least 3 different ways in which the division and modulo instructions are implemented, but there were only 3 combinations we cared about here.

Each of these sequences returned a single number, and those four numbers were combined (via some basic arithmetic and translation tables) to produce a final value in the range 0 to 22. That value could then be used as an index to lookup the actual message to display.