Print Polyglot Pieces
GolfScript + CJam + Fission 2 + Jelly, 4 languages, 24 bytes, score 2.667
Let's start with the hex dump:
00000000: 3322 3024 700a 2721 2b4f 5222 0a3c 3024 700a 6523 7fff cccc
For GolfScript, CJam and Fission 2, we interpret this in some ASCII-compatible single-byte encoding like ISO 8859-1 (the exact encoding doesn't really matter, because the languages only define operators for ASCII characters anyway):
3"0$p
'!+OR"
<0$p
e#<DEL>ÿÌÌ
Where <DEL>
is the control character 0x7f
.
In Jelly, this is assumed to be in Jelly's own code page, where it looks like this instead:
3"0$p½'!+OR"½<0$p½e#¶”ṘṘ
GolfScript
The e
on the last line is an unknown variable and #
comments out the remainder of the line, so this prints
"0$p"
0$p
with a trailing linefeed. This is the GolfScript/CJam polyglot version of the standard quine:
".p"
.p
Try the polyglot. | Try the quine.
CJam
Here, e#
comments out the last line, so almost identically, this prints
"0$p"
0$p
without a trailing linefeed.
Try the polyglot | Try the quine.
Fission
Fission only sees the second line which is the standard Fission quine, so it prints
'!+OR"
I can't provide an online link for the polyglot here, because TIO sends the file to Fission as UTF-8, but Fission reads the source byte by byte, which makes the last line too long. However, I've tested this locally with an ISO 8859-1 encoded file (in which the last line has the same length as the second), to confirm that this works.
Try the quine.
Jelly
The pilcrow is an alias for linefeeds in Jelly, so the source is equivalent to:
3"0$p½'!+OR"½<0$p½e#
”ṘṘ
All but the last line of a Jelly program are "helper links" (i.e. functions) which can be ignored unless they are called, provided they are syntactically valid. This is actually the reason the 3
comes first in the CJam and GolfScript programs, because otherwise the "
can't be parsed in Jelly.
Otherwise, since the function isn't called, the program is equivalent to only its second line, which is the standard Jelly quine.
Try the polyglot. | Try the quine.
><> + Python, 2 languages, 51 46 bytes, score~=0.16 0.17
Since there are no answers yet, I'll start with a simple one
#.09;!?lo}*2+2f"
_='_=%r;print _%%_';print _%_
Try it for ><> and Python
For ><> the first line is a quine (# reflects, " puts the whole line on the stack, then we push 34 (charcode for ") and print everything) , execution never moves from it, so it effectively ignores the rest of the code.
For Python the first line is a comment, while the second one is a quine (standard approach in python, using string substitution with the same string as both arguments).
JavaScript + Python 2 + Japt, 3 languages, 132 bytes, score ~= 0.205
A="`i96d)p2`i96d)p2";1//2;A=1
S="S=%s;console.log(S,uneval(S))";A//2;S="S=%r;print S%%S";"""
console.log(S,uneval(S))//""";print S%S
This prints
S="S=%s;console.log(S,uneval(S))";console.log(S,uneval(S))
in JavaScript (only in Firefox),
S='S=%r;print S%%S';print S%S
in Python 2, and
`i96d)p2`i96d)p2
in Japt. (Test it online!)
JavaScript
This is what JavaScript sees:
A="`i96d)p2`i96d)p2";1
S="S=%s;console.log(S,uneval(S))";A
console.log(S,uneval(S))
The first line is a no-op because A
is not used in any way. The second line sets S
to the string S=%s;console.log(S,uneval(S))
, and the third prints it after replacing the %s
with the uneval
ed representation of S
(just S
wrapped in quotes). The result is a quine in JavaScript.
Python
This is basically what Python sees:
A="`i96d)p2`i96d)p2";1//2;A=1
S="S=%s;console.log(S,uneval(S))";A//2;S="S=%r;print S%%S"
print S%S
The first line is pretty much a no-op; the only important part is the A=1
at the end. This turns A
into a number so that the integer division A//2
on the second line doesn't throw an error.
The second line is mostly the same way, except it sets S
to the string S=%r;print S%%S
. The third line prints S
after replacing the %r
with the raw representation of S
(just S
wrapped in single-quotes). The result is a quine in Python 2.
Japt
This is the JavaScript code the Japt interpreter sees:
A="`i96d)p2`i96d)p2";1//2;A=1
S="S=%s;console.log(S,uneval(S))";A//2;S="S=%r;print S%%S";"","\nconsole.log(S,uneval(S))//","";.p("r".i("n".t(),S%S))
As you can see, it's mostly the same as the JavaScript answer, with one main exception: the last two lines are combined. As a result, this is what the interpreter actually sees:
A="`i96d)p2`i96d)p2";1
S="S=%s;console.log(S,uneval(S))";A
The first line sets A
to the Japt quine, and the second sets S
to part of the JS quine. In Japt however, only the last expression is sent to output; this is A
, so the output is `i96d)p2`i96d)p2
.