Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

The task is to write a code which compiles in as many languages as possible, in as few characters as possible. To avoid trivial solutions, the program must print the name of the language it is compiled or interpreted in.

It has to work with at least 5 languages.

Scoring: (n is the number of languages)

(n * sqrt(n)) / code_length

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

share|improve this question
Would using a solution like using print() for Perl, Python, PHP, Processing and R be considered trivial or is it acceptable? – Mike Dtrick Sep 10 '12 at 23:34
2  
A can't see a problem with it. The difficulty would be switching print's input per language. – mjgpy3 Sep 11 '12 at 2:57
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 – vsz Sep 11 '12 at 18:47
I was going to suggest that too. Based on the answers provided, I don't believe I interpreted your question properly. – Mike Dtrick Sep 11 '12 at 23:10

7 Answers

up vote 10 down vote accepted

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.

share|improve this answer

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++.

share|improve this answer
would it be shorter if you output brainf***? – mob Sep 11 '12 at 20:15
Yes it would, I believe. – mjgpy3 Sep 12 '12 at 3:42

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
share|improve this answer
1  
Wow, a solution that does not include C – vsz Sep 11 '12 at 20:11

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
share|improve this answer

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)

share|improve this answer

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
share|improve this answer

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

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

if(typeof arguments!="undefined")
 alert("CoffeeScript")
else if(typeof WScript!="undefined")
 WScript.echo("JScript")
else if(typeof uneval!="undefined")
 alert("Mozilla JavaScript")
else if(Array.prototype.map)
 alert("ECMAScript 5")
else
 alert("ECMAScript 3") 
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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