65
\$\begingroup\$

Your task is to write a program that executes in as many languages as possible, with as few characters as you can. To avoid trivial solutions, the program must print the name of the language it was run in.

Scoring

Your program has to work in at least 5 languages. A program's score is given as:

(number of languages)1.5 / (length of program)

The highest score wins, not sooner than 10 days after the first valid answer.

\$\endgroup\$
  • \$\begingroup\$ Would using a solution like using print() for Perl, Python, PHP, Processing and R be considered trivial or is it acceptable? \$\endgroup\$ – Rob Sep 10 '12 at 23:34
  • 3
    \$\begingroup\$ A can't see a problem with it. The difficulty would be switching print's input per language. \$\endgroup\$ – mjgpy3 Sep 11 '12 at 2:57
  • \$\begingroup\$ I should have given a higher weight to the number of languages... it seems choosing to have exactly 5 is the most optimal. I wonder how many languages would have been in the winner entry if the score were n * n / length \$\endgroup\$ – vsz Sep 11 '12 at 18:47
  • \$\begingroup\$ I was going to suggest that too. Based on the answers provided, I don't believe I interpreted your question properly. \$\endgroup\$ – Rob Sep 11 '12 at 23:10

14 Answers 14

38
\$\begingroup\$

Bash, C, C++, Obj-C, Obj-C++, Perl, PHP, Ruby, 183 chars

score ~ 0.1236

For the C and C-like codes I owe a debt to @baby-rabbit. The others are inspired by the recognition that many languages have an eval statement that will grudgingly accept invalid syntax.

Outputs the language name to standard output. Sometimes generates a lot of error messages on standard error, so suppress them with 2>/dev/null as you run them.

#if 0
'PHP<?/*';eval "print\$=?'Perl':'Ruby';echo Bash";exit
__END__
#endif
#include <stdio.h>
main(){puts(
#ifdef __OBJC__
"obj-"
#endif
"C"
#ifdef __cplusplus
"++"
#endif
);}//*/?>'

The php solution outputs 'PHP' (including the single quotes), which may be bending the rules a little bit.

Last edit: shaved 12 chars from insight that $= is false in Ruby, 60 in Perl, and print$=?... is almost surely an error in Bash. Shaved 7 more from insight the Perl/Ruby/Bash test can now go into a single eval statement.

If the rules can tolerate more bending, I present this 8 language, 43 character solution (score 0.5262)

print("phperluarscriptrubypythoncatebg13");

for which the output includes the name of the interpreter for php, perl, lua, rscript, ruby, python, cat, and rot13.

\$\endgroup\$
  • 1
    \$\begingroup\$ TI-Basic supports the last one; just add 6 characters and get print("phperluarscriptrubypythontibasicatebg13"); \$\endgroup\$ – Timtech Dec 31 '13 at 0:36
  • 1
    \$\begingroup\$ @Timtech no, TI-Basic uses the Disp or Output( or text( tokens, there is no print( command. And including a string as part of an otherwise real-valued expression results in an ERR:INVALID SYNTAX, not the display of the string (not even as a return value). (Also, there is no ;; TI-Basic uses :) \$\endgroup\$ – AJMansfield Feb 5 '14 at 21:57
  • \$\begingroup\$ @AJMansfield Too true, how could I forget :? \$\endgroup\$ – Timtech Feb 5 '14 at 23:17
  • 12
    \$\begingroup\$ Can you replace echo Bash with ps -ocomm= -p$$? This will output the name of the shell for at least bash, zsh, ksh, csh and tcsh, maybe others. \$\endgroup\$ – Digital Trauma May 30 '14 at 19:22
19
\$\begingroup\$

C, C++, BF, BASH and Ruby; 280 chars

Score is about 0.040

#include "stdio.h"
#define s "C"
#ifdef __cplusplus
#define s "C++"
#endif
#ifndef s
#"+++++++++[>++++++++++>+++++++++<<-]>>-.<++++.>-.++++++++.<----.>---.<+++++++.>---.++++++++.<<++++++++++.[-]"
if [ 1 == 2 ];then
puts "Ruby"
exit
fi
echo "BASH"
exit
end
#endif
main(){puts(s);}

Note that I am using a Linux system.

The code is run or compiled with the following commands (the file's name is test.c)

C:

gcc test.c

When run with ./a.out, output is C

C++:

c++ test.c

When run with ./a.out, output is C++

BASH:

./test.c

Outputs: BASH

Ruby:

ruby test.c

Outputs: Ruby

BrainF***:

Verified using the following:

Outputs: brainfuck

Note that if the JS debugger is used, then the first two minus signs need to be removed. They were included to offset the plus signs in the string literal "C++". This was a very fun project, I'm working on adding more languages.

Just to add further clarity, here are my interpreter's/compiler's specs:

  • gcc version 4.6.3

  • ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]

  • GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)

SIDE NOTE

Using @baby-rabbit's trick I was able to extend my code to be executable in 7 languages (objective-C and objective-c++ being added). This is not my solution since I did copy some, but I thought I would show it off.

Update 9.12 Added SmallTalk run with gnu-smalltalk!

SmallTalk, C, C++, Objective-C, Objective-C++, BASH, BF, Ruby; 384 chars (Score: 0.059)

#if (a)
##(true) ifTrue: ['SmallTalk' printNl]
##(ObjectMemory quit)
#"+++++++++++[>++++++++++>+++++++++<<-]>>-.<++++.>-.++++++++.<----.>---.<+++++++.>---.++++++++.<<++++++++++.[-]"
if [ 1 == 2 ];then
puts 'Ruby'
exit
fi
echo 'BASH'
exit
end
=begin
#endif
#include "stdio.h"
main(){puts(
#ifdef __OBJC__
"Objective-"
#endif
"C"
#ifdef __cplusplus
"++"
#endif
);}
#ifdef b
=end
#endif

In the above code you will need to rename the file to produce the langauge's name for objective-c, obj-c++, c and c++.

\$\endgroup\$
  • \$\begingroup\$ would it be shorter if you output brainf***? \$\endgroup\$ – mob Sep 11 '12 at 20:15
  • \$\begingroup\$ Yes it would, I believe. \$\endgroup\$ – mjgpy3 Sep 12 '12 at 3:42
  • \$\begingroup\$ You should use if [ 1 = 2 ] instead of if [ 1 == 2 ], because scripts without a hashbang are executed by sh, not bash. sh may or may not be bash, on Debian it's dash. \$\endgroup\$ – nyuszika7h May 1 '14 at 15:13
12
\$\begingroup\$

bash, c, c++, obj-c, obj-c++; 134 chars; score=0.083

#if x
echo "bash"
exit
#endif
#include <stdio.h>
int main(){puts(
#ifdef __OBJC__
"obj-"
#endif
"c"
#ifdef __cplusplus
"++"
#endif
);}

rename file and run/compile as:

  • sh file.sh
  • cc file.c
  • cc file.cpp
  • cc file.m
  • cc file.mm

(where cc is clang-421.10.42)

\$\endgroup\$
  • \$\begingroup\$ +1 since many other upvoted answers were inspired by yours. \$\endgroup\$ – Kevin Jan 1 '14 at 21:17
11
\$\begingroup\$

Lua, Ruby, VimL, Sed, Befunge (129 chars; ~0.087 points)

Not sure if this one counts--the sed-part is embedded in the shebang line which is arguably a hack to get around the restriction. This also means that it should be run as an executable and not directly with sed.

I was lucky that all the other languages (sans Befunge) automagically ignores the shebang line (though apparently Ruby refuses to run the file if it has a shebang line that doesn't contain the string 'ruby' in it).

#!sed sanava;s/.*/sed/;q;ruby
--"".to_i#>"egnufeB">:#,_@
if 0
then
if IO
then
puts"Ruby"
else
print"Lua"
end
else
echo"VimL"
end

Sample usage:

% lua tmp/glot.poly
Lua
% ruby tmp/glot.poly
Ruby
% ./tmp/glot.poly
sed
% cfunge tmp/glot.poly       # Requires Befunge-98
Befunge

:source tmp/glot.poly        # from vim
VimL                         # displayed as message
\$\endgroup\$
  • 5
    \$\begingroup\$ Wow, a solution that does not include C \$\endgroup\$ – vsz Sep 11 '12 at 20:11
8
\$\begingroup\$

BF, Bash, Batch, C, vi (163 characters; score ≈ .0686)

(<ESC> stands for ASCII code 27.)

rem (){ ((0));};true /*
rem ;goto(){ rem;}
rem ivi<ESC>ZZ'++++++++[>NUL ++++++++<NUL -]>NUL ++.++++.*/;main(){puts("C");}/*'
goto a
echo Bash
exit
:a
echo Batch
rem */

I tested this, as a batch file, with the MS-DOS 6.22 version of COMMAND.COM. By default, that interpreter mixes lines of source code with the output. To prevent that from happening, execute echo off before running the batch file.

To execute the vi code, which I have only tested using Vim, use the following command:

cat /dev/null > tmpfile && vi -s polyglot.sh tmpfile > /dev/null 2>&1 && cat tmpfile
\$\endgroup\$
  • 1
    \$\begingroup\$ You could use touch tmpfile or : > tmpfile instead of cat /dev/null > tmpfile. \$\endgroup\$ – nyuszika7h Dec 30 '13 at 22:32
5
\$\begingroup\$

bash, zsh, ksh, csh, tcsh, 15 chars, score 0.745

This one's a bit of a stretch since they're all related languages, but there are differences:

ps -ocomm= -p$$
\$\endgroup\$
  • \$\begingroup\$ What about dash? \$\endgroup\$ – Elliot A. Feb 6 '16 at 15:37
4
\$\begingroup\$

Every Python Release, 18.37291 points

import sys
print('Python '+'.'.join(map(str,sys.version_info[:-2])))

Technically valid, if you consider all the python versions to be different languages. There are currently 116 python versions, which I believe gives me a score of around 18.37291.

(Also I understand if this isn't considered a valid answer, this was just for fun)

\$\endgroup\$
3
\$\begingroup\$

Bash, C, Gawk, Perl, vi (145 characters; score ≈ .077)

(<BS> stands for ASCII code 8. <ESC> stands for ASCII code 27.)

#define echo//<BS><BS><BS>vi<ESC>ZZ
#define BEGIN A()
#define B\
{
echo Bash ;exit;
#define C\
}
BEGIN {printf(A=="A"?"Perl":"Gawk");exit;}
main(){puts("C");}

To execute the vi code, which I have only tested using Vim, use this command:

cat /dev/null > tmpfile && vi -s polyglot.sh tmpfile > /dev/null 2>&1 && cat tmpfile
\$\endgroup\$
3
\$\begingroup\$

This is a cheap selection of languages, but here goes:

CoffeeScript, JScript, Mozilla Javascript (≈ JavaScript 1.3), ECMAScript Edition 5, ECMAScript Edition 3, 223 chars, score ≈ 0.0501)

a="undefined"
x="ECMAScript 3"
if(Array.prototype.map)
 x="ECMAScript 5"
if(typeof CoffeeScript!=a)
 x="CoffeeScript"
if(typeof uneval!=a)
 x="Mozilla JavaScript"
if(typeof WScript!=a)
 WScript.echo("JScript")
else alert(x)
\$\endgroup\$
  • 5
    \$\begingroup\$ JavaScript, JavaScript, JavaScript (≈ JavaScript), JavaScript, JavaScript, 263 chars, (score ≈ 0). you can also make it shorter a="undefined";if(typeof arguments!=a)...else if(typeof WScript!=a... oh and you can also try golfing it.... \$\endgroup\$ – Math chiller Oct 21 '13 at 12:22
  • \$\begingroup\$ @tryingToGetProgrammingStraight Putting everything on one line like that is not valid syntax in CoffeeScript (which is a separate language from Javascript). The others are arguable, but since it wasn't specified how different the languages have to be, I think the fact that the different implementations have different specified behaviors allows them to be treated as separate. \$\endgroup\$ – Peter Olson Oct 21 '13 at 14:56
  • \$\begingroup\$ i also cant write a multi-line comment, the only golfing you seem to have used is leaving out {/}/;... the idea is to use a to avoid reusing "undefined", you could also do b=alert and then b("this is also still just javascript"). anyway The golden rule of CoffeeScript is: "It's just JavaScript" (from coffeescript.org), you can also use some jquery to add a sixth language.... \$\endgroup\$ – Math chiller Oct 21 '13 at 15:55
  • 1
    \$\begingroup\$ @tryingToGetProgrammingStraight Adding jQuery would be absurd, since jQuery is a library, not a language. CoffeeScript is definitely not the same language as ECMAScript. The definition of a language is a set of finite strings over a finite alphabet. The set of strings representing valid CoffeeScript programs is not the same as the set of strings representing valid ECMAScript. \$\endgroup\$ – Peter Olson Oct 22 '13 at 21:57
  • 1
    \$\begingroup\$ Can you do [].map instead of Array.prototype.map? \$\endgroup\$ – ETHproductions Feb 6 '16 at 21:24
3
\$\begingroup\$

Java, Lisp, Whitespace, Intercal, PHP, Befunge-98; score =.0189

This was originally an answer to this.

 ;\\0"egnufeB">:#,_@SSSTTTSTTTL
;TL
;SSSSSTTSTSSSL
;TL
;SSSSSTTSTSSTL
;TL
;SSSSSTSTSTSSL
;TL
;SSSSSTTSSTSTL
;TL
;SSSSSTSTSSTTL
;TL
;SSSSSTTTSSSSL
;TL
;SSSSSTTSSSSTL
;TL
;SSSSSTTSSSTTL
;TL
;SSSSSTTSSTSTL
;SSL
;L
;L
;L
;public class H{ public static void main(String []a){System.out.println("JAVA");}}
;/*
(print "LISP")
;*/
;//<?php
; echo "PHP"
;//?>
;/*
#|
DO ,1 <- #8
DO ,1 SUB #1 <- #110
DO ,1 SUB #2 <- #32
DO ,1 SUB #3 <- #72
DO ,1 SUB #4 <- #136
DO ,1 SUB #5 <- #88
DO ,1 SUB #6 <- #136
PLEASE DO ,1 SUB #7 <- #64
DO ,1 SUB #8 <- #80
PLEASE READ OUT ,1
PLEASE NOTE |#
;*/
;// PLEASE GIVE UP
\$\endgroup\$
  • \$\begingroup\$ This won't work in Java; every line until public class... will cause a compiler problem. \$\endgroup\$ – Ypnypn May 1 '14 at 2:53
  • \$\begingroup\$ Interesting... I distinctly remember testing this in a compiler and it working... or perhaps my memory fails me... \$\endgroup\$ – Juan Sebastian Lozano May 1 '14 at 2:55
  • \$\begingroup\$ @Ypnypn Remember that "T" is a tab,"S" is a space, and "L" is a line feed in white-space, which is why it does not cause a compiler error. \$\endgroup\$ – Juan Sebastian Lozano May 1 '14 at 2:57
  • \$\begingroup\$ Oh; that makes sense. \$\endgroup\$ – Ypnypn May 1 '14 at 2:58
3
\$\begingroup\$

Windows Batch, TI-Basic, Golf-Basic 84, Quomplex, and GTB 5*2/93 = 0.11

::¤Quomplex¤:"'*[]'":~"GTB":g;1:d`"GOLF-BASIC 84":g`1:"TI-BASIC":Lbl 1:End
echo Windows Batch

How it works

Windows Batch was the easiest, because :: starts a comment. Fairly simple to implement.

TI-Basic doesn't support lowercase letters or backticks, causing it to skip the statements d`"GOLF-BASIC 84":g`1, which Golf-Basic evaulates, Displaying the message and forwarding to Label 1, where it is promptly ended. This is similar for GTB, with its handy display character, ~. By the way, a string with no display will be put in Ans. If there are no Display commands following it, Ans will be outputted (not the case here).

Quomplex was snuck in at the beginning because its complex syntax won't allow for much to be skipped. All it does is add "Quomplex" to the output, and then for the mastery of the program...

The Mastery of the Programming Syntax

:"'*[]'"

Pure genius. Quomplex ignores : and takes "' and '" as strings, leaving it to output the stack and perish in an infinite while loop ([]). Meanwhile, Golf-Basic and TI-Basic take the whole "'*[]'" as a string, because ' is a mathematical operator, not a string operator.

\$\endgroup\$
  • \$\begingroup\$ Strictly speaking, : indicates a label in a batch file, not a comment. It's true that it doesn't execute anything on its own, though. \$\endgroup\$ – Mark Apr 24 '14 at 20:19
  • \$\begingroup\$ @Mark True, but is is :: (still a label though). I'd rather use it than REM, especially since it is required in TI-Basic. \$\endgroup\$ – Timtech Apr 24 '14 at 22:13
  • \$\begingroup\$ Right - I was just being pedantic. Also, +1 for using batch files in the first place. :-) \$\endgroup\$ – Mark Apr 25 '14 at 0:26
2
\$\begingroup\$

JScript, EcmaScript Edition 3, 5, 6, 2016, Node, Mozilla JavaScript (score ≈ 0.1342)

This answer is originally based off Peter Olson's answer, but minus the CoffeeScript (as whitespace-significant languages can be horrible for golfing).

I also added Node, ES6 and ES2016 and golfed the code a little, almost tripling the original score.

$=this,y="EcmaScript ",x=$.module?"Node":$.uneval?"Mozilla JavaScript":"".padStart?y+2016:$.Map?y+6:[].map?y+5:y+3,($.WScript||$.alert)(x)
\$\endgroup\$
2
\$\begingroup\$

16 languages, 348 bytes, score: 0.183908046

#include <stdio.h>
#if 0
#replace "C(gcc)" "C(ecpp)"
#replace "C++(gcc)" "C++(ecpp)"
#endif
#ifdef __clang__
#define d 2
#elif __TINYC__
#define d 4
#else
#define d 0
#endif // rk:start print: "rk" \
ps -ocomm= -p$$; exit;
int x=sizeof('a')%2+d;char*arr[]={"C(gcc)","C++(gcc)","C(clang)","C++(clang)","C(tcc)"};int main(){puts(arr[x]);}

This works in C(gcc), C++(gcc), C(ecpp), C++(ecpp), C(clang), C++(clang), C(tcc), sh, dash, bash, zsh, ksh, csh, tcsh, rk, and SIL.

\$\endgroup\$
0
\$\begingroup\$

JScript, EcmaScript Edition 3, 5, 6, 2016, 2017, Node, Mozilla JavaScript (score = .174193548387), CoffeeScript (as whitespace-significant languages can be horrible for golfing).

$=this,y="EcmaScript ",($.WScript||alert)(x=Object.values?y+2017:$.module?"Node":$.uneval?"Mozilla JavaScript":[].includes?y+2016:$.Map?y+6:[].map?y+5:y+3)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.