Write a polyglot that prints the language's name
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
.
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:
A JS debugger
A free interpreter
My interpreter
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++.
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)