247
106
This is an answer-chaining challenge in which each answer builds on the previous answer. I recommend sorting the thread by "oldest" in order to be sure about the order in which the posts are made.
Note: This has become quite a long-lasting challenge, and posting new answers is fairly difficult. As such, there's now a chat room available for this challenge, in case you want advice on a particular part of a potential answer, have ideas for languages that could be added, or the like. Feel free to drop in if you have anything to ask or say!
The task
The nth program to be submitted must run in n different languages; specifically, all the languages added in previous programs to be submitted, plus one more. The program must output 1 when run in the first language used in answers to this question, 2 when run in the second language, and so on. For example, the first answer could print 1 when run in Python 3, and the second answer could output 1 when run in Python 3 and 2 when run in JavaScript; in this case, the third answer would have to output 1 when run in Python 3, 2 when run in JavaScript, and 3 when run in some other language.
Additional rules
Your program must run without erroring out or crashing. Warnings (and other stderr output) are acceptable, but the program must exit normally (e.g. by running off the end of the program, or via a command such as
exit
that performs normal program termination).The output must be only the integer, but trailing newlines are OK. Other unavoidable stdout output is also allowed. Examples: interpreter name and version in Befunge-93, space after printed string in Zephyr. Some languages provide two methods of printing – with and without trailing space; in this case method without trailing space must be used.
Each answer must be no more than 20% or 20 bytes (whichever is larger) longer than the previous answer. (This is to prevent the use of languages like Lenguage spamming up the thread, and to encourage at least a minor amount of golfing.)
- Using different versions of the same language is allowed (although obviously they'll have to print different numbers, so you'll need to fit a version check into the polyglot). However, you may not use a language feature that returns the language's version number. Repeating the exact same language is, obviously, impossible (as the program would have to deterministically print one of two different numbers).
- Tricks like excessive comment abuse, despite being banned in some polyglot competitions, are just fine here.
- You don't have to use the previous answers as a guide to writing your own (you can rewrite the whole program if you like, as long as it complies with the spec); however, basing your answer mostly on a previous answer is allowed and probably the easiest way to make a solution.
- You cannot submit two answers in a row. Let someone else post in between. This rule applies until victory condition is met.
- As this challenge requires other competitors to post in the same languages you are, you can only use languages with a free implementation (much as though this were a cops-and-robbers contest).
- In the case where a language has more than one interpreter, you can pick any interpreter for any given language so long as all programs which are meant to run successfully in that language do so in that interpreter. (In other words, if a program works in more than one interpreter, future posts can pick either of those interpreters, rather than a post "locking in" a particular choice of interpreter for a language.)
- This challenge now uses the new PPCG rules about language choice: you can use a language, or a language interpreter, even if it's newer than the question. However, you may not use a language/interpreter that's newer than the question if a) the language was designed for the purpose of polyglotting or b) the language was inspired by this question. (So newly designed practical programming languages are almost certainly going to be OK, as are unrelated esolangs, but things like A Pear Tree, which was inspired by this question, are banned.) Note that this doesn't change the validity of languages designed for polyglotting that are older than this question.
- Note that the victory condition (see below) is designed so that breaking the chain (i.e. making it impossible for anyone else to answer after you via the use of a language that is hard to polyglot with further languages) will disqualify you from winning. The aim is to keep going as long as we can, and if you want to win, you'll have to respect that.
Answer format
As all the answers depend on each other, having a consistent answer format is going to be helpful. I recommend formatting your answer something like this (this is an example for the second link in the chain):
2. JavaScript, 40 bytes
(program goes here)
This program prints 1 in Python 3, and 2 in JavaScript.
(if you want to explain the program, the polyglotting techniques, etc., place them here)
Victory condition
Once there have been no new answers for 14 days, the winner will be whoever posted the second newest answer, i.e. the largest polyglot that's been proven not to have broken the chain. Extending the chain after that is still very welcome, though!
The winner is Chance, see answer 194 (TemplAt).
Language list
// This snippet is based on the snippet from hello world thread https://codegolf.stackexchange.com/questions/55422/hello-world
// It was tested only in Google Chrome
// https://stackoverflow.com/a/4673436
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, (match, number) => (typeof args[number] != 'undefined' ? args[number] : match) );
};
}
var QUESTION_ID = 102370; // from the question url
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
function answersUrl(index) {
return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}
var answers = [], answer_page = 1;
function getAnswers() {
jQuery.ajax({
url: answersUrl(answer_page++),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
answers.push.apply(answers, data.items);
if (data.has_more) { $('#status').text($('#status').text() + '.'); getAnswers(); }
else process();
},
// [Documentation](http://api.jquery.com/jquery.ajax/) states that `error` handler is not called for cross-domain JSONP requests,
// but it works here, probably because api.stackexchange.com and codegolf.stackexchange.com are on the same domain.
error: function (a,b,c) {
$('#status').text( "Failed to load answers: " + b + " " + c );
console.log( b + " " + c );
},
});
}
getAnswers();
// https://stackoverflow.com/questions/6290442/html-input-type-text-onchange-event-not-working/39834997#39834997
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event
const input = document.querySelector('input');
input.addEventListener('input', onSearchInput);
function onSearchInput(e)
{
var table = document.getElementsByTagName("table")[0];
var str = e.srcElement.value.toLowerCase();
var num_results = 0;
if(str == "") // optimization for empty input
{
// show all rows
for(var i = 1, row; row = table.rows[i]; i++)
{
row.className = "";
num_results++;
}
}
else
{
for(var i = 1, row; row = table.rows[i]; i++)
{
var hidden = row.innerText.toLowerCase().indexOf(str) == -1;
if(!hidden) num_results++;
row.className = hidden ? "hidden" : "";
}
}
document.getElementById("results").innerText = "Results: " + num_results;
}
/* Function ParseHeader() extracts answer number, language name and size of polyglot from answer header.
Argument: `header` - answer header string without markup, eg. "1. Python 3 (8 bytes)" or "59. Tcl, 1324 bytes".
Retval: object, eg. {num: 1, language: "Python 3", size: 8} or
null if header has wrong format
There are two formats of header, new one with comma and old one with parens.
Parsing new format only with regexp is hard because:
- language name may contain commas, eg. "51. Assembly (x64, Linux, AS), 1086 bytes"
- there may be several sizes, of which the last one should be used, eg. "210. Haskell without MonomorphismRestriction, 10035 9977 bytes"
There are only several answers with old format header: 1-5, 7, 12-17, 21. All of them have single size and don't have parens in language name,
so they can be parsed with simple regexp.
Algorithm: Find commas. If there are no commas parse it as old format. Otherwise parse it as new format.
New format parsing: Let everything after last comma be `sizes`. Check if `sizes` ends with the word "bytes". If not, set size to 0.
Take the word before "bytes" and convert it to number. Parse the rest of the header (before last comma) with regexp.
*/
function ParseHeader(header)
{
var a = header.split(',');
if(a.length > 1) // current format: Number "." Language "," Size+ "bytes"
{
// filter(s=>s) removes empty strings from array (handle multiple consecutive spaces)
var sizes = a[a.length-1].split(" ").filter(s=>s); // " 123 100 bytes " -> ["123", "100", "bytes"]
var size;
if(sizes.length < 2 || sizes[sizes.length-1] != "bytes") size = 0;
else size = +sizes[sizes.length-2];
a.splice(a.length-1,1); // remove last element
var match = a.join(',').match(/(\d*)\.(.*)/);
if (!match) return null;
return{
num: +match[1],
language: match[2].trim(),
size: size,
};
}
else // old format: Number "." Language "(" Size "bytes" ")"
{
var format = /(\d*)\.([^(]*)\((\d*)\s*bytes\)/;
var match = header.match(format);
if (!match) return null;
return{
num: +match[1],
language: match[2].trim(),
size: +match[3]
};
}
}
// 1533246057 (number of seconds since UTC 00:00 1 Jan 1970) -> "Aug 2 '18"
// other useful Date functions: toUTCString, getUTCDate, getUTCMonth, getUTCFullYear
function FormatDate(n)
{
var date = new Date(n*1000); // takes milliseconds
var md = date.toLocaleDateString("en-US", {timeZone:"UTC", day:"numeric", month:"short"});
var y = date.toLocaleDateString("en-US", {timeZone:"UTC", year:"2-digit"});
return md + " '" + y;
}
var processed = []; // processed answers, it's called `valid` in original snippet
function ProcessAnswer(a)
{
var body = a.body, header;
//
// Extract header from answer body.
// Try find <h1> header (markdown #). If not found try find <h2> (markdown ##).
// Extracted header contains only text, all markup is stripped.
// For 99 language markup is later readded to language name because markup is essential for it.
//
var el = document.createElement('html'); // dummy element used for finding header
el.innerHTML = body;
var headers = el.getElementsByTagName('h1');
if(headers.length != 0) header = headers[0].innerText;
else {
headers = el.getElementsByTagName('h2');
if(headers.length != 0) header = headers[0].innerText;
else { console.log(body); return; } // error: <h1> and <h2> not found
}
var info = ParseHeader(header)
if(!info) { console.log(body); return; } // error: unrecognised header format
if(info.num == 99 && info.language == "99") info.language = "<i>99</i>";
processed.push({
num: info.num,
language: info.language,
size: info.size,
answer_link: a.share_link,
user: a.owner.display_name,
user_link: a.owner.link, // `undefined` if user was deleted
creation_date: a.creation_date, // unix epoch (number of seconds since UTC 00:00 1 Jan 1970)
});
}
function process()
{
$('#status').remove();
answers.forEach(ProcessAnswer); // answers -> processed
processed.sort( (a,b)=>(a.num-b.num) ); // sort by answer number, ascending
processed.forEach(function (a) {
var date = FormatDate(a.creation_date);
var user = a.user_link ? ('<a href="'+a.user_link+'">'+a.user+'</a>') : a.user; // redundant code, currently the only deleted user is ais523
if(user == "user62131") user = '<a href="https://chat.stackexchange.com/users/246227/ais523">ais523</a>';
var style = (a.num == 194) ? "background: #ccf" : ""; // 194 is winner answer
var row = "<tr style='{0}'><td>{1}</td> <td><a href='{2}'>{3}</a></td> <td>{4}</td> <td>{5}</td> <td>{6}</td></tr>"
.format(style, a.num, a.answer_link, a.language, a.size, user, date);
$('#answers').append( row );
});
}
a {text-decoration:none}
a:visited {color:#00e}
table, td, th { border: 1px solid black; }
td, th { padding-left: 5px; padding-right: 5px; white-space: nowrap; }
tr:hover { background-color: #ff9; }
td:first-child { text-align:center; } /* # */
td:nth-child(4) { font-style:italic; } /* author */
td:nth-child(5) { text-align:right; } /* date */
p { margin: 8px 0px }
.hidden { display: none } /* search hides rows */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<span>Search: </span><input autofocus> <span id="results"></span>
</p>
<table class="answer-list">
<thead>
<tr><th>#</th> <th>Language</th> <th>Size (bytes)</th> <th>Author</th> <th>Date</th></tr>
</thead>
<tbody id="answers">
</tbody>
</table>
<div id="status">Loading answers...</div>
3
For people who can see deleted posts: the Sandbox post was here.
– None – 2016-12-06T19:00:09.6531How should permalinks be updated? Should the newest answer contain permalinks of all the previous languages? – user41805 – 2016-12-06T19:41:37.170
5There's no need to copy the previous program, although of course you can use it as a guide; redoing the program from scratch is likely to take longer! There's no need to permalink to answers; sorting by oldest will show all the answers in order already. – None – 2016-12-06T19:44:38.350
3@ais523 I think what was meant was that should new answers contain try it links with the new code? – Blue – 2016-12-06T19:45:46.623
In hindsight there could have been a requirement to check validity of answers before new answers can be posted, e.g. in meta regex golf.
– Sp3000 – 2016-12-07T09:31:21.583Is it ok if the language does not have an online interpreter, but has one on github (but has to be downloaded)? – user41805 – 2016-12-07T09:38:59.820
As PPCG rules require allowing as many languages to compete as reasonably possible, I don't think it can be fair to require there to be an online way to test the program (and the post as currently written doesn't), although you must of course give people some way to test. Perhaps you could try to persuade one of the online language hosts to add the language you're thinking of, though, to make things easier? – None – 2016-12-07T13:14:15.747
@ais523 I have already written an online interpreter (based on the GH code) for haystack, but I will ask someone to add the language on TIO, thanks! – user41805 – 2016-12-07T18:11:05.980
5I think we need a script that takes a hex dump of the code and automatically runs it in all the languages... – mbomb007 – 2016-12-07T20:05:06.333
Is it okay to exit with a non-zero error code that is not crashing, e.g. Befunge-98's
q
command? – Sp3000 – 2016-12-07T21:07:58.313@Sp3000: Yes. Intentionally reporting failed execution is distinct from a crash. – None – 2016-12-07T21:37:03.313
3
This is the Versatile integer printer posted as a different type of challenge. (Inspiration?) The final answer (currently) would score
– Stewie Griffin – 2016-12-17T12:11:47.8270.0127
, only beaten by Sp3000's 30 language submission... :)1
@StewieGriffin I actually just added a snippet to my last answer that shows the scores for all the answers if they'd been submitted for that challenge
– SnoringFrog – 2017-02-06T17:27:49.867This challenge is perfectly described by its tags: [polyglot] [answer-chaining]. – Esolanging Fruit – 2017-05-29T20:52:36.793
Can we use languages that were "created" (pushed to GitHub) barely a month after the challenge? – MD XF – 2017-06-02T02:34:43.337
@MDXF: Unfortunately no. PPCG rules are fairly frustrating for a challenge like this, but if you start violating them, you end up in a subjective minefield of what is and isn't legal. – None – 2017-06-02T06:21:54.720
@ais523 that's disappointing. I was going to add ;# cause it's quite easy – caird coinheringaahing – 2017-06-05T17:05:11.380
@cairdcoinheringaahing I really doubt it would be as easy as you think. There are quite a few
#
's in the code, and it wouldn't be possible to just add random;
's. – MD XF – 2017-06-05T22:03:57.007@MDXF it's probably the easiest language of all of them to add given that it was designed for polyglot Kolmogorov complexity challenges (# and ; are common comment symbols – caird coinheringaahing – 2017-06-05T22:09:43.760
@StewieGriffin it is now under
0.003
:) – MD XF – 2017-07-31T18:22:04.473@cairdcoinheringaahing Yeah, except there are already about 300 instances of
#
in the code. – MD XF – 2017-07-31T18:22:59.9471This challenge has been linked from the Wikipedia article on Polyglots. – pppery – 2017-08-20T02:09:25.983
Are we going to award the accepted answer to anyone else than stasoid and potato44? Because they did most of the answers? – Michthan – 2017-09-27T06:21:43.303
@Michthan The accepted answer would have gone to the winner, which in this case is the second newest answer when 14 days have passed since the most recent answer. But because ais523 is no longer a member of PPCG no answer will get accepted as he isn't here to do so. – Potato44 – 2017-09-27T07:21:00.517
For authors of similar challenges (in which bigger thing is built based on previous answers): please, don't prohibit a user from adding several answers in a row. This rule is harmful. It gave me a LOT of trouble, I had to wait for weeks, sometimes for months to add an answer. That was absolutely agonizing. This rule together with winning condition artificially creates competition for inherently collaborative challenge. Note that having winning condition is not obligatory - e.g. hello world challenge explicitly does not have one.
– stasoid – 2018-07-09T03:12:00.563@stasoid It's code-golf. – user202729 – 2018-07-09T14:22:05.003
1@stasoid A compromise might be something like: You cannot post two answers in a row within less than 7 days. That means you can get two answers in a row only once things start slowing seriously down. – Ørjan Johansen – 2018-07-09T19:09:05.900