##JavaC++C, 363/27 = 13.4....
Java prints 1, C++ prints 2, C prints 3. Not breaking any records here (because Java), but I really like the clever, abusive way of making a polyglot in these languages that I discovered.
//\u000a/*
#include<stdio.h>
#ifdef __cplusplus
#define o "2"
#else
#define o "3"
#endif
int p(int a){printf(o);}
struct{int(*print)(int);}out;
//*/
/*\u002a/
import static java.lang.System.out;
public class P{//*/
/*\u002a/public static void//*/
main(/*\u002a/String[] args//*/
){//\u000a/*
out.print=p;
//\u002a/
out.print(1);}
/*\u002a/}//*/
This is a mess. Here's a breakdown of how it works. The Unicode literals (`\u000a`, otherwise known as a linefeed, and `\u002a`, otherwise known as `*`) are expanded by the Java compiler into their actual characters. So, here is what the Java compiler sees:
<!-- language: lang-java -->
//
/*
#include<stdio.h>
#ifdef __cplusplus
#define o "2"
#else
#define o "3"
#endif
int p(int a){printf(o);}
struct{int(*print)(int);}out;
//*/
/**/
import static java.lang.System.out;
public class P{//*/
/**/public static void//*/
main(/**/String[] args//*/
){//
/*
out.print=p;
//*/
out.print(1);}
/**/}//*/
All that stuff in the beginning is ignored because it's all wrapped in a multi-line comment (`/* ... */`). Later on, we see that mixing single-line and multi-line comments allows us to control exactly which parts are commented out in each language. In the main method, we start a multi-line comment, and then have `//*/`. Ordinarily, this would be a single-line comment, but since we are in a multi-line comment, the `//` doesn't do anything, allowing the `*/` to close it.
This is the equivalent Java code, with comments removed:
<!-- language: lang-java -->
import static java.lang.System.out;
public class P{
public static void
main(String[] args
){
out.print(1);}
}
Here is what the C/C++ compiler sees (I've removed the Unicode literals, since they are not expanded by the compiler and thus don't do anything):
<!-- language: lang-c++ -->
///*
#include<stdio.h>
#ifdef __cplusplus
#define o "2"
#else
#define o "3"
#endif
int p(int a){printf(o);}
struct{int(*print)(int);}out;
//*/
/*/
import static java.lang.System.out;
public class P{//*/
/*/public static void//*/
main(/*/String[] args//*/
){//\/*
out.print=p;
///
out.print(1);}
/*/}//*/
Here, the single-line comments override the multi-line comment delimiters in the beginning, so all of the `#define`s and the `#include` get preprocessed. Next, multi-line comments are used to comment out the boiletplate code for Java. This is the equivalent code, with comments removed:
<!-- language: lang-c++ -->
#include<stdio.h>
#ifdef __cplusplus
#define o "2"
#else
#define o "3"
#endif
int p(int a){printf(o);}
struct{int(*print)(int);}out;
main(
){
out.print=p;
out.print(1);}
A standard C/C++ polyglot trick (the `#ifdef __cplusplus`) is utilized to define a token `o` as either `"2"` or `"3"`, depending on if it's a C++ or a C compiler that is compiling the code. Next, we define a funtion `p` that takes a single (ignored) `int` argument and calls `printf`, using our newly-defined `o` token. As per usual, the return value is left out, since we're not in strict mode. Next, we define a `struct` with a single member, a function pointer whose signature matches `p`'s, and construct a single instance named `out`. In the main method (we leave off the `int` as usual), the address of `p` is assigned to `out.print` (so calling `out.print` calls `p`), and it is called.
If C++ wasn't included in the languages, we could drop all of the preprocessor code, and define `p` as `int p(int a){puts("2");}`. Unfortunately, C++ requires an `#include` to do I/O. If C wasn't included, we could drop the definition of `p` and the `#ifdef` preprocessor macro, and directly define a member function in the `struct` instead of needing a function pointer. Unfortunately, C does not support member functions.