18
\$\begingroup\$

From Quine central:

Write a quine that takes as input the name of a language and outputs the same thing implemented in the input language.

The source article has something you can work from, but as the author says this is much harder. Obviously you only need to support a limited set of languages. The choice is yours though, as well as the base language.

As a , your score will be the number of languages your program supports; higher is better.

\$\endgroup\$
10
  • \$\begingroup\$ Catchy title... \$\endgroup\$
    – FlipTack
    Jan 4, 2017 at 20:05
  • \$\begingroup\$ Define "number of languages". \$\endgroup\$
    – Adám
    Jan 4, 2017 at 20:08
  • \$\begingroup\$ @Adám: Well, the point of the challenge is to write a program that supports a set of languages, as follows: giving it the name of any of the languages as input will output an equivalent program in that language. The number of languages in which the program works is the size of the set. This isn't my challenge (just one I bountied), so I don't think there's an "official" source on corner cases; as such, we can and should all collaboratively edit the challenge to make it better/clearer without changing the meaning. \$\endgroup\$
    – user62131
    Jan 4, 2017 at 20:19
  • \$\begingroup\$ @ais523 What's to stop us from writing a polyglot quine that takes input and does nothing with it? That'd be perfectly legal according to these rules. \$\endgroup\$
    – mbomb007
    Jan 6, 2017 at 16:00
  • \$\begingroup\$ @mbomb007: it is legal, but might not be the easiest way to answer the question. Polyglot quines can often be hard to fit additional languages into, whereas the question as currently worded doesn't require you to write a polyglot (and can be solved via a set of universal quine constructors, one in each language you use). \$\endgroup\$
    – user62131
    Jan 6, 2017 at 17:36

2 Answers 2

5
\$\begingroup\$

Ruby

require 'json';s=%q[{"ruby":[" %q[","require 'json';s=##;j=JSON.load s;puts j[l=gets.chomp][1].sub('##',j[l][0].delete(' ')+s+j[l][2].delete(' '))"," ]"],"python":["' ''","import json,re;s=##;j=json.loads(s);l=raw_input();print(re.sub('##',j[l][0].replace(' ','')+s+j[l][2].replace(' ',''),j[l][1],1))","' ''"]}];j=JSON.load s;puts j[l=gets.chomp][1].sub('##',j[l][0].delete(' ')+s+j[l][2].delete(' '))

Python

import json,re;s='''{"ruby":[" %q[","require 'json';s=##;j=JSON.load s;puts j[l=gets.chomp][1].sub('##',j[l][0].delete(' ')+s+j[l][2].delete(' '))"," ]"],"python":["' ''","import json,re;s=##;j=json.loads(s);l=raw_input();print(re.sub('##',j[l][0].replace(' ','')+s+j[l][2].replace(' ',''),j[l][1],1))","' ''"]}''';j=json.loads(s);l=raw_input();print(re.sub('##',j[l][0].replace(' ','')+s+j[l][2].replace(' ',''),j[l][1],1))

Both versions take input on stdin (ruby or python currently) and generate the output to stdout in either language.

\$\endgroup\$
3
+200
\$\begingroup\$

Turtlèd, Python 2, and Python 3, 3 languages, only competing for bounty

all oneliners follwed by newline

Turtlèd

@##'@r,r,r-{ +.r_}r{ +.r_}!!-.(3"';m=ord(input()[-1]);_='x=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))';print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"367>;++[ d( d)('.)]d<"x='"))(2"';m=ord(raw_input()[-1]);_='x=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))';print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"371>;++[ d( d)('.)]d<"x='"))(d' )#'@r,r,r-{ +.r_}r{ +.r_}!!-.(3"';m=ord(input()[-1]);_='x=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))';print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"367>;++[ d( d)('.)]d<"x='"))(2"';m=ord(raw_input()[-1]);_='x=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))';print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"371>;++[ d( d)('.)]d<"x='"))(d' )

Try it online!

Python 2

x='@##y@r,r,r-{ +.r_}r{ +.r_}!!-.(3"y;m=ord(input()[-1]);_=yx=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))y;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"367>;++[ d( d)(y.)]d<"x=y"))(2"y;m=ord(raw_input()[-1]);_=yx=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))y;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"371>;++[ d( d)(y.)]d<"x=y"))(dy )#y@r,r,r-{ +.r_}r{ +.r_}!!-.(3"y;m=ord(input()[-1]);_=yx=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))y;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"367>;++[ d( d)(y.)]d<"x=y"))(2"y;m=ord(raw_input()[-1]);_=yx=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))y;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"371>;++[ d( d)(y.)]d<"x=y"))(dy )';m=ord(raw_input()[-1]);_='x=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))';print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))

Try it online!

Python 3

x='@##y@r,r,r-{ +.r_}r{ +.r_}!!-.(3"y;m=ord(input()[-1]);_=yx=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))y;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"367>;++[ d( d)(y.)]d<"x=y"))(2"y;m=ord(raw_input()[-1]);_=yx=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))y;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"371>;++[ d( d)(y.)]d<"x=y"))(dy )#y@r,r,r-{ +.r_}r{ +.r_}!!-.(3"y;m=ord(input()[-1]);_=yx=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))y;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"367>;++[ d( d)(y.)]d<"x=y"))(2"y;m=ord(raw_input()[-1]);_=yx=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))y;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))"371>;++[ d( d)(y.)]d<"x=y"))(dy )';m=ord(input()[-1]);_='x=%r;m=ord(input()[-1]);_=%r;print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%%(x,_) if m==50 else _%%(x,_) if m==51 else x.replace(chr(121),chr(39)))';print(_.replace(chr(100)+chr(40),chr(100)+chr(40)+chr(114)+chr(97)+chr(119)+chr(95))%(x,_) if m==50 else _%(x,_) if m==51 else x.replace(chr(121),chr(39)))

Try it online!

Explanation:

For each language, I took already written quines and modified them a bit.

Turtlèd first:

Turtlèd includes the standard quine structure. however, should the input end with a 2 or a 3, it appends the end of the python code, either 2 or 3, it includes them both separately, to the quine output, and then goes back to the start and adds x='. Otherwise the sourcecode is left and output like a regular quine

Also note it takes input twice !!., because the source contains a newline which feeds to input an empty line.

however, along the way to the start of string, in order to avoid the fact that the string cannot have ' in it, it changes all the ' in the main source along the way to y. if it did, quote escaping could be annoying, if even possible

this relies on a trick; I could not have written (''y), (pseudocode:if cell is ', write y), because then that y would have been indistinguishable from a '. so, I use the y from the input "Python"! this was a real eureka moment for me.

then, there are the python quinelike things.

How the python quinelike thing works:

it works like a regular quine, except it also includes the variable x

if it has input Python 3, it works like a regular quine, and uses % formatting to also include the source for Turtlèd.

if it has input Python 2, it replaces input in the string with raw_input, and does otherwise the exact same thing.

if input is Turtlèd, it replaces the ys in the Turtlèd source and prints it.

The two python programs function the same, and take input the same way

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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