304
\$\begingroup\$

This is an 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 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.)

  • If some interpreter gets updated and the program no longer works in the newer version then new answers can either stick to the old version or fix the program to work in the new version.

  • 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> &nbsp;<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>

\$\endgroup\$
28
  • 4
    \$\begingroup\$ For people who can see deleted posts: the Sandbox post was here. \$\endgroup\$
    – user62131
    Commented Dec 6, 2016 at 19:00
  • 6
    \$\begingroup\$ There'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. \$\endgroup\$
    – user62131
    Commented Dec 6, 2016 at 19:44
  • 4
    \$\begingroup\$ @ais523 I think what was meant was that should new answers contain try it links with the new code? \$\endgroup\$
    – Blue
    Commented Dec 6, 2016 at 19:45
  • 7
    \$\begingroup\$ I think we need a script that takes a hex dump of the code and automatically runs it in all the languages... \$\endgroup\$
    – mbomb007
    Commented Dec 7, 2016 at 20:05
  • 5
    \$\begingroup\$ This is the Versatile integer printer posted as a different type of challenge. (Inspiration?) The final answer (currently) would score 0.0127, only beaten by Sp3000's 30 language submission... :) \$\endgroup\$ Commented Dec 17, 2016 at 12:11

451 Answers 451

1
2 3 4 5
16
88
\$\begingroup\$

Note: If you see this first, you might want to sort by oldest

17. Julia (128 bytes)

#v`16 "<" 6/b0\ .q@#;n4"14""
#>3N9@15o|R"12"*^
#=|
print((1/2and 9 or 13)-(0and+4)^1<<65>>62);# =#;print(17)
#gg99ddi2` |1|1+6

There are two ESCs on the last line, one before the first g and one after the 2. This could be golfed more, but things got messy no thanks to V and Pyth.

Prints 1 in Python 3, 2 in V, 3 in Minkolang, 4 in ><>, 5 in Python 2, 6 in SMBF, 7 in Japt, 8 in Retina, 9 in Perl, 10 in Befunge-93, 11 in Befunge-98, 12 in Fission, 13 in Ruby, 14 in Turtléd, 15 in Haystack, 16 in Pyth and 17 in Julia.


Hints:

  • The start of the fourth line is Python 2/3, Perl, Ruby. The end is Julia, thanks to #= multiline comments (note that Julia doesn't have and/or).
  • V is <ESC>gg99ddi2<ESC>, which is definitely golfable but V is annoying to test on Try it online! since the interpreter is fairly slow.
  • Minkolang and Haystack go down at the first v. Befunge-93 and -98 don't, and depend on a b.
  • Retina counts the number of spaces and 1s in the fourth line, and V hides in the config for Retina (i.e. before the backtick).
  • Per @ETHproduction's hint, Japt uses backticks to hide the majority of the code in a string.
  • Fission is R"12"*.
  • SMBF has been golfed to <. in the first line, plus the final 6.
\$\endgroup\$
9
  • 27
    \$\begingroup\$ Where has everyone else's code gone though \$\endgroup\$ Commented Dec 7, 2016 at 14:56
  • 16
    \$\begingroup\$ 159 bytes to 128 bytes? Wow, that's some excellent golfing! \$\endgroup\$
    – user41805
    Commented Dec 7, 2016 at 15:00
  • 7
    \$\begingroup\$ Nice, 2^7 bytes \$\endgroup\$
    – tomsmeding
    Commented Dec 7, 2016 at 15:45
  • 8
    \$\begingroup\$ Wow... incredible! We're going to have to write up a new explanation for every language when all's said and done ;-) \$\endgroup\$ Commented Dec 7, 2016 at 17:32
  • 4
    \$\begingroup\$ @AlfieGoodacre "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)" \$\endgroup\$
    – mbomb007
    Commented Dec 7, 2016 at 20:07
61
+100
\$\begingroup\$

50. bash, 1024 bytes

#16  "(}23!@)" 3//v\D(@;'[af2.qc]GkGGZ'#)"14";n4
#/*` "[!PPP(22)SP(>7 7*,;68*,@;'1,@ ␉␉␉␉ q
#>␉
# >36!@␉
#`<`
#<]+<[.>-]>[
#{
#z}
#
#=<xR+++++[D>+++++++L+++<-][pPLEASE,2<-#2DO,2SUB#1<-#52PLEASE,2SUB#2<-#32DOREADOUT,2DOGIVEUPDOiiipsddsdoh@O6O4/]>+.-- -. >][
#Rx%>~~~+ +~*ttt*.x
#D>xU/-<+++L
#R+.----\).>]|
#[#[/v/v(/0l0v01k1kx0l0ix0jor0h0h1d111x0eU0bx0b0o1d0b0e0e00m1d0i0fx0g0n0n11x0o0n0cx0c0o0f0c0gx0g0f0h0j0j0i0001k10vx0v0l111111^_)  0046(8+9+9+9+9+=!)
###|
'\';echo 50;exit;';print((eval("1\x2f2")and(9)or(13))-(0and 4)^1<<(65)>>(62))or"'x"or'({({1})({1}[(0)])}{1}\{1})'#}#(prin 45)(bye)|/=1/24=x<$+@+-@@@@=>+<@@@=>+<?#d>+.--./
__DATA__=1#"'x"//
#.\."12"__*'
###;console.log 39
""""#//
=begin //
#ssseemeePaeueewuuweeeeeeeeeeCisajjapppp/*/
#define z sizeof'c'-1?"38":"37"
#include<stdio.h>
main(  )/*/
#()`#`\'*/{puts(z );}/*'``
<>{# }//
#}
disp 49#//
#{
1}<>//
$'main'//
#-3o4o#$$$
#< >"3"O.
=end #//
"""#"#//
#}
#|o51~nJ;#:p'34'\
#ss8␛dggi2␛ `|1|6$//''25  =#print(17)#>27.say#]#print(47)#]#echo 21#ss*///nd^_^_Z222999"26

Want to learn more? Try the polygot chat!

Try them online!

As usual, I replaced literal tabs with and literal ESC characters with , due to limitations of Stack Exchange. You can get an easily copiable version of the program from the "input" box of the TIO link above.

Rundown

This program prints 50 in bash, 49 in Octave, 48 in Deadfish~, 47 in Lily, 46 in Cubix, 45 in PicoLisp, 44 in alphuck, 43 in reticular, 42 in evil, 41 in brainf***, 40 in Minimal-2D, 39 in CoffeeScript, 38 in C, 37 in C++, 36 in Labyrinth, 35 in INTERCAL, 34 in Rail, 33 in Incident, 32 in Whirl, 31 in Modular SNUSP, 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng, 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.

Verification

Most of the languages are tested by the test driver above. The usual four culprits need testing separately:

  • Incident was tested using its official interpreter, offline;

  • Deadfish~ was also tested using its official interpreter, offline;

  • Modular SNUSP was tested online here;

  • Reng was tested online here.

Explanation

I was looking at various leads for languages to add. One possibility was to find a language with # line comments that could plausibly be added to the "scripting language" line (which handles Perl, Python 2 and 3, and Ruby). It took me a while to think of an appropriate language that could be syntax-compatible with the ones already there, though.

It turns out that the answer had been staring me in the face for ages. If you click the TIO link above, it'll open up the polyglot test driver, which is written in bash. So all this time, I had a tab saying "Bash — TIO Nexus". You'd have thought that'd be a hint, but apparently I missed it. As a bonus, bash is also a scripting language, so the term "scripting language line" is still appropriate.

The bash program starts in the same place as the other scripting languages. However, there's a fairly simple way to split it away from them; in single-quoted strings, \ is an escape character in most languages, but not in bash. So we can hide bash code from the other languages via '\'…';, which is a degenerate statement (with no effect) in Perl, Python, and Ruby, but executed in bash. echo 50;exit is a fairly simple way to end the bash program. Well, almost.

The biggest problem here is that bash will, upon running exit, continue parsing until the end of the current line (even though it doesn't execute the code in question), so we need to make sure there are no syntax errors on the rest of the line. We have a ' just after exit; that isn't (and cannot be) immediately matched. Later on on the line, '…' is used to hide some Brain-Flak code from the scripting languages, but that would unhide it from bash. As a result, we need to change what sort of string literal we're using to hide the code, going from single-quoted to double-quoted strings. or"'" does the trick without disturbing Perl, Python, or Ruby (as the left-hand argument is truthy in every case).

We now have an unmatched double quote that extends onto a future line. It was fairly hard to close it without disturbing at least one other language; what we actually do is to change the way we hide code from bash from double quote back to an unmatched single quote in a Python/Ruby comment on the subsequent line, and finally close the single quote at the end of the line after that.

Pyth and 05AB1E

Messing around with double quotes also disturbs the languages that were using double-quoted strings to hide code, Pyth and 05AB1E. The main trick we use here is to ensure that every double quote we add has another double quote soon afterwards in order to expose as little code as possible. (This explains the extra double quote on the __DATA__ line, which isn't necessary for bash.) Pyth uses \ as an escape character; the main upshot of this is that it limited the scope I had for messing around with strings in the scripting languages, forcing me to use the rather convoluted method above (as I couldn't easily make use of the difference in \ behaviour between bash and everything else). In 05AB1E, ' acts as an escape character outside strings, and having it escape the leading " wouldn't do. So I ended up needing to place a useless padding character (defaulting to my usual x; it makes things easier to read!) inside the "'" constructs that are used to change between bash quoting styles.

Prelude

By far the hardest language to fix here. The problem is that the scripting line, with all its parentheses, was moved sideways, and thus the Prelude control flow (which cares a lot about the way in which parentheses are vertically aligned) was completely destroyed. I thus had to try to reconstruct something that works.

Worse, the current first line (which I really didn't want to rewrite) places something of a hard limit on where the parentheses can appear. It starts off with a nonzero digit (two of them, in fact!), and is soon followed by an opening parenthesis. That's a loop in Prelude, and loops early on in the control flow in Prelude cause a number of different issues (mostly because they cause more code to run, rather than less). As such, I badly needed to open a 0-iteration loop on some other line in order to skip over that code. The main line for the C program is highly suitable, but we need to be very careful with where the matching closing bracket is; too far right and the unmatched bracket on the #R+ line will cause trouble, too far left and it won't comment out enough code. (Bear in mind that an opening parenthesis on one line can match a closing parenthesis o a different line.)

Once that's done, we have just enough space to stick in an opening parenthesis on the Incident line, and we've finally got safely past the first few characters of the program. However, the difference in parenthesis placements ends up meaning that some of the Incident/Whirl code actually runs in Prelude, corrupting the stack. Instead of trying to prevent this, I moved some of Whirl's zeroes further to the right, allowing them to give us a working Prelude program again.

One other small change was on the first line of the program; the final parenthesis of the line was in a position that was very hard to avoid. I added an extra c just after the Pyth code to shift it to the right. (Many languages are parsing that point of the program, so it took a surprising amount of trial and error to find a padding character that wouldn't break at least one language!)

Incident

Prelude was hard enough by itself, but getting Prelude and Incident working at the same time was nightmarish. Prelude placed a lot of constraints on the code which prevented me freely moving things around, and thus made accidental token construction harder to golf out. For example, Prelude only really needs one 0 moved out to the right, but that caused 00 to become a failed token, breaking some of the tokens we wanted as part of the Incident program (because if two tokens overlap, they're both rejected, and the 00 was overlapping a token we wanted in addition to overlapping itself). I had to move both out to make a fourth copy and prevent it being even considered as a token.

More subtle are the tokens ;' and ␠␠ (i.e. two space characters). The issue is that these both appear before the kG that is being used to jump to the start of the program, and thus will break Incident's control flow (in addition to breaking the program's centre point).

Removing a copy of ␠␠ by breaking it up doesn't seem viable. Removing it via overlapping it might be possible (␠= is a promising potential overlap), but it's almost certainly less verbose to just add a fourth copy, which is what I did here.

Meanwhile, we can use a different trick for ;'. Breaking it up isn't something I wanted to try, given that it's used in fairly spacing-sensitive situations. However, it's not that near the start of the program (despite appearing on the first line), so it's plausible that we could jump over it (thus causing it to not affect control flow) rather than needing it to not exist. I looked for a suitable token to use for the jump which wouldn't screw up any of the other languages. /v appears a little earlier on the first line, and doesn't break anything, and thus that's what I used.

50 languages in 1 Kib of code

It was pointed out by @MistahFiggins that my 1025-byte submission would be way neater if it were 1024 bytes (especially as the fiftieth language is a milestone in its own right). This required finding a byte of savings somewhere. In this case, I saved three bytes in the Deadfish~, at the costs of two extra bytes used to make Incident tokens line up correctly, and thus bringing the program down to 1024 bytes exactly.

Previously, the formula that the Deadfish~ code used was (2²+2)²+10×1+2 = 48. The new formula is (3²-2)²-1, also producing 48. Surprisingly, it isn't that much shorter to write in Deadfish~, despite being considerably simpler.

This also gives us a VIP score of .008192. Not only is this a new record, it's also a nicely round number in its own right (which is, obviously, a consequence of having nice round numbers as the inputs to the formula).

\$\endgroup\$
11
  • 4
    \$\begingroup\$ Sorry for not having a TIO >_> (Sincerely, creator of Reng) \$\endgroup\$ Commented Mar 21, 2017 at 3:46
  • 1
    \$\begingroup\$ @ConorO'Brien Ping Dennis? Also, ais523, you should try to golf a single byte off ;) \$\endgroup\$ Commented Mar 21, 2017 at 3:50
  • 1
    \$\begingroup\$ You can cut the space in puts(z ) if you swap ( and P in line 2, thanks you the prelude leeway you've created. Bravo on this answer. #50in1k \$\endgroup\$
    – Chance
    Commented Mar 21, 2017 at 4:41
  • 1
    \$\begingroup\$ As it happens, I golfed off a different byte. Now it's at 1024 exactly I don't really want to change it :-) Perhaps a later answer can save some of the savings we have; there are likely a lot more (e.g. there's likely old Incident padding/detokenisation lying around that's no longer needed). \$\endgroup\$
    – user62131
    Commented Mar 21, 2017 at 4:46
  • 7
    \$\begingroup\$ @ais523 agreed. This answer was always meant to be 1024 bytes. \$\endgroup\$
    – Chance
    Commented Mar 21, 2017 at 4:47
56
\$\begingroup\$

23. Hexagony, 186 bytes

Sorry if this messes up plans...

#v`16/"<"6/b.q@"(::):::  (22)S#;n4"14"
#>3N6@15o|> ^*ttt*~++~~~%
#=~nJ<R"12";
#[

print((1/2and 9 or 13)-(0and+4)^1<<65>>62)#46(89999+++++!)=#print(17)#0\32=""<0]#echo 21
#8␛dggi2␛` |1|6

␛ is used to represent a literal ESC character.

Prints:

23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng (testable here), 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in Vim/V, and 1 in Python 3.

To get to the unlinked languages, click the change language button in the upper right of the Hexagony link.


Hexagony isn't readable (at ALL) in this format. We need to look at it in hexagonal form.
Note that the 2 ESC characters have been replaced with s so you can see them - they are ignored, so there are no others in the program:

        # v 1 6 / " < " 6
       / b . q @ " ( : : )      A lot more readable, right?? No?
      : : : ( 2 2 ) S # ; n
     4 " 1 4 " # > 3 N 6 @ 1
    5 o | > ^ * t t t * ~ + +
   ~ ~ ~ % # = ~ n J < R " 1 2
  " ; # [ p r i n t ( ( 1 / 2 a
 n d 9 o r 1 3 ) - ( 0 a n d + 4
) ^ 1 < < 6 5 > > 6 2 ) # 4 6 ( 8   | Note that the 0s below can be replaced
 9 9 9 9 + + + + + ! ) = # p r i    | With anything (except "`" or " "), 
  n t ( 1 7 ) # 0 \ 3 2 = " " <     V as far as Hexagony is concerned
   0 ] # e c h o 2 1 # 8 ␛ d g
    g i 2 ␛ | 1 | 6 . . . . .    <-- the ␛ represents an esc
     . . . . . . . . . . . .         character
      . . . . . . . . . . .
       . . . . . . . . . .       A "." is a no-op
        . . . . . . . . .
                ^
                | Mirror wraps to here, going NW

For those unfamiliar with Hexagony, There are 6 IPs, which start at the 6 corners. Only 1 is active at a time, and are switched by using #][. The memory model isn't that important to this program, but might be necessary to understand in the future. All that you need to know is that 1 int is stored in a "memory edge" (ME for short), and '"}{ change the ME that is active.

\/|_>< are mirrors that control program flow.

This is how it works:

First line executed:

#       A no-op (sets active IP to 0, the currently active one)
 v      letter chars set the ME to their ASCII value - so ME is now 118
  16    Like Labyrinth, 0-9 multiplies ME by 10 and is added - ME now 11816
    /   A mirror that sends IP going NW by wrapping to the bottom

The bottom (snippet flipped vertically so you can read up to down):

    .   
   .    A series of no-ops. The IP is going NW now,
  .     because of the mirror on the top.
 .
|       Another mirror. This one sends the IP NE, into the h
 h      sets the ME to 104, the ASCII value for h
  #     104 % 6 == 2, so IP 2 is now active instead of 0

The right edge:

        8  IP #2 is moving SW, starting in the right corner 
       i   Sets the ME to 105
      <    Mirror. Sends the IP going due West
    ""     These change the Active ME - just know that the new edge is 0
   =       Changes the MP (more in specs) - effectively a no-op used to fill space
\32        pushes 23, and mirrors up NE to the !

The last bit of relevant code:

!          Prints the current value of the ME as an int. Success!
 20(R~     Does things to the ME - irrelevant now
      @    Ends the program!

Things to note:

  • Hexagony drops all s and `s before executing, so any changes to those will not affect Hexagony
  • I needed to pad the code so that it would be interpreted as a 9 length hexagon, instead of an 8th - be careful golfing below 169 or above 217 relevant characters
  • Because of this, the ~~~ and the 2 0s at the end can be changed at no harm to the code
  • The ="" just moves the ME away from the previous one so that a new ME can be modified. They can be replaced with other characters that do the same thing at no harm to the hexagony program ('s, for example)
  • This is technically not comlient with the Befunge 93 specs, because it limits the bounding box of the code to 80 by 25 chracters. However, Most interptreters ignore this spec (like TIO), So I don't personally think it's that big of a deal. If you do, feel free to leave a comment. (If enough really want me to change it, then I will try)
  • Hope it's not too hard now.
\$\endgroup\$
9
  • 1
    \$\begingroup\$ This could easily become the most crazy program flow if done right. I was close to getting it done with a size 8 hexagon through some crazy @## method, but 9 was a lot easier once I tried that. Also, v1 of TIO works a lot faster, but you can't switch languages easily. \$\endgroup\$ Commented Dec 9, 2016 at 5:38
  • \$\begingroup\$ I would suggest Labyrinth next, but I want to do that one. \$\endgroup\$ Commented Dec 9, 2016 at 5:46
  • \$\begingroup\$ I'm not skilled enough to write anything like this myself, but in the mean time I'm waiting for Cubix to pop up. \$\endgroup\$
    – Pavel
    Commented Dec 9, 2016 at 6:22
  • \$\begingroup\$ @pavel I'm not familiar with that language. I assume it's 3D. Sounds cool. There's also some funges that are 3D, might be an interesting addition \$\endgroup\$ Commented Dec 9, 2016 at 6:36
  • \$\begingroup\$ I suspect it's easiest to maintain something like this flow as long as we're still at this side length, and just rewrite the Hexagony code when we go up to the next size. With respect to 3D languages, Trefunge should be fairly easy to fit in, assuming that none of the existing languages panic upon seeing formfeeds. (Also, Cubix was posted earlier but deleted because the poster thought it might be too hard; maintaining Hexagony and Cubix at once could be fairly confusing…) \$\endgroup\$
    – user62131
    Commented Dec 9, 2016 at 7:49
40
+500
\$\begingroup\$

37. C++ (gcc), 776 bytes

#  1"16" 2//v\(;@#/;n4"14"
#/*`3 auaaZ<>16/"<"6/b.q@")(22)S#  ␉␉␉␉ 
#yy␉;36!@
# ␉
#=␉>
#[#yy#yy0l0mx01k1k0l0ix0jx0h0h1d111P0eU0bx0b0o1d0b0e0e00x1d0i0fx0g0n0n11x0o0n0cx0c0o0f0c0gx0g0f0h0j0j0i0001k10mx0m0l11111100(^_)
#`<`␉|
print((eval("1\x2f2")and( 9 )or(13 ))-(0and 4)^1<<(65)>>(62))or'(\{(\{})(\{}[()])}\{}\{}\{})'#46(8+9+9+9+9+=!)#1|=/=1/24=x=9[<$+@+-@@@@=>+<@@@=>+<?#>+.--.]/
__DATA__=1#//
#.\."12"*␉
""""#//
=begin␉//
#*/
#include<iostream>␉
int main()  /*/
#()"`#"\'*/{std::cout<<37;}/*'"`"
$'main'␉//
#-3o4o#$$$
<>3N.<>␉//
#xx
#x%~~~+␉+~*ttt*.x
#xx
=end   #//
"""#"#//
#0]#echo 21#/(\[FAC,1<-#2FAC,1SUB#1<-#52FAC,1SUB#2<-#32FACLEGEREEX,1PLEASEGIVEUPPLEASE)  ap
#_~nJ|#o51\   
#0␛dggi2␛`␉|1|6$//''25  >>>>>#>27.say# =#print(17)#^_^_7LEintndus({})!<>+]/*///Z222999/3!@"26

is a literal tab, a literal ESC character; Stack Exchange would mangle the program otherwise. I recommend copying the program from the "input" box of the TIO link below, if you want to work on it.

Try them online!

Rundown

This program prints 37 in C++, 36 in Labyrinth, 35 in INTERCAL, 34 in Rail, 33 in Incident, 32 in Whirl, 31 in Modular SNUSP, 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng, 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.

Verification

Most of the languages are tested by the test driver shown above. You can test Reng here and Modular SNUSP here; they output 19 and 31 respectively, as required.

I added another format to the test driver output that escapes double quotes as well as make line feed replacements. This is so I can feed the single line string to a c(gcc) program I wrapped around the function created by @feersum here. Hopefully others can make use of it as is.

Here's the Incident token program. Ideally I'd like to deliminate the tokens since they are a bit hard to read, indicate the "center" token, and include it in the test driver. But I don't really know how to do anything other than make various programs print sequential integers, so this is as far as I've gotten.

I've attempted to solve the obvious Incident problems, like tokens after the beginning and end jump tokens and anything that looked extraneous, but I haven't balanced the tokens to put 0o at the center. I'm not really sure what the logic is exactly to determine the center. I'm hoping @ais523 will help there. This string near the end 7LEintndus({})!<>+ would all be tokens if not for this 4th inclusion in the code. These can all be removed (and replaced with a . for Hexagony alignment) in order to adjust the center token.

I'm going to be updating this post off and on over the next day or two to walk through the code, (assuming Incident can be verified/fixed without going over the byte count). But it's super late now, and I mostly wanted to get this out there before I had to solve another Labyrinth like problem. :P

Explanation

How the C++ code works.

I think most people are familiar enough with C++, so I won’t go into too much detail. Block comments come in the form of /* comment */. Line comments come in the form of //comment. The actual code utilized by C++ to produce the answer is int main() {std::cout<<37;}. And the library that’s used to interface with STDOUT is referenced by this statement #include<iostream>.

/*Comments Abuse*/

For me, the story of C++ goes back to my Brain-Flak answer.

After finally finding #28, I set out to study some other polyglots posted in PPCG and all that studying led me to a few easy answers (most of these are still available to be found if anyone else is so inclined). But more importantly, I came to a conclusion about polyglots in general: large polyglots tend to fall into one of two broad categories: # comment abuse or /* comment abuse.

This is not a fact or restriction in anyway, but of a personal mental framework that guided my next several answers.

From here I reasoned that if this was to become the world’s largest polyglot, which I presume it to be currently, it would be best if it could leverage comment abuse from both comment families. So I set out to find a way incorporate a /* comment language and pushed towards the C family due mostly to a personal familiarity.

C++ Initial Test

My initial thought process for this was to use C# mostly because of my familiarity and the first hurdle for C# was getting the polyglot into a state where it could accept a line that didn’t start with # without otherwise being treated as code by the scripting languages. The Rail answer, along with several byte inflating answers that lead up to it, solved this piece.

Next came the problem of how to initiate the first /* comment block. I knew the line would have to start the line with a # to remain invisible to Perl, Ruby and Python, but whatever came before the /* would be read by C#. I attempted a C# #region tag at first, but that turned out to be too ridged for the 2D languages. Enter C++.

C++ has several preprocessor directives that all start with #, which give a lot of options for the 2D languages to traverse. But it turned out that all of them were incompatible with at least one language, and being in a C++ exposed code space, I had limited workarounds. Out of frustration and desperation, I stumbled into the fact that C++ would simply accept just a single # before the comment block. Okay, whatever, that’s workable. So I moved forward with the presumption that #/* could work as the first three characters in the polyglot.

The second piece of basic verification was to ensure that the actual print statement could live happily with the other codes. I knew from the Brain-Flak answer that Japt didn’t like un-escaped {’s and that was needed for C++ to say int main() {std::cout<<37;} and C++ wouldn’t allow Japt’s escape character in the middle of its code. This time I was lucky enough to find that if I dropped out of Japt’s literal string just for this statement, Japt would still happily produce the same result.

Meanwhile, Brain-Flak didn’t like the {} either, but I was again lucky to find that C++ was ok with a # between its int main() and {std::cout<<37;} statements, allowing the curly braces to be commented out of Brain-Flak’s perspective.

So, with the main problems of C++ proven to be theoretically solvable, I began the arduous process of resolving all the errors I’d introduced.

2D Landscape

The hardest part of this answer was by far the reconfiguration of the top two lines of the polyglot. And the most significant problem was the *. Underload will not allow a * prior to a (. It considers this as math operation on an empty stack, which it feels is an error. So the polyglot required a ( prior to the /* but C++ couldn’t allow this. So the solution was to us a C++ line comment // on the first line to hide a ( and then start the second line with a #/*.

Next, Befunge really didn’t like the idea of a / without something being divided but after studying the existing Begunge answer of 16/"<"6/b.q@ I stumbled on the idea of a number and a string smashed together ahead of the //. It worked and I have no idea why C++ is ok with this but it accepts # 1"16" 2 as it’s opening statement. I’m not going to question it, but I do know that the spaces are required for it to work.

Line One

Japt turned out to be rather space sensitive and didn’t really want to enter into its backtick based string on the top line, so it and Pip’s backtick got moved to the second line, forcing a lot of linguistic gymnastics on line 1.

  • Pip didn’t like most of line 1, so a second space was placed after the first #to indicate a comment.
  • The ( for Underload had to be escaped out of Japt with a preceding \.
  • # is a jump terminator in Turtlèd so it was required, but Pyth considers this a error terminating loop, so Pyth needed a divide by null / after the #
  • I’m not sure what the @ in the first line is doing anymore, but Pyth and Japt seem to like it’s presence better than not, although @ is not a meaningful character according to Pyth’s documentation.
  • And it looks like the first ; can be removed at this point without consequence, so I’m not sure what was being solved there anymore, although I suspect it was Pyth related. But it looks like future solutions can save a byte by omitting that one.
  • <>< and Turtlèd both basically work the same as before with <>< reflecting on the first # and wrapping to the end of line one. And Turtlèd jumps with # like I mentioned and ends with the "14" string which it prints.

2D routing

With these issues resolved, the next phase was routing the 2D languages. Previously the initial v was ignored by the Befunges due to the preceding #, but sent Haystack and Minkolang down. Now, the initial space attempts to send Minkolang along the 3rd dimension, which its documentation refers to as the time dimension.

Quick aside on Minolang’s 3rd dimension: to me it’s something of a misnomer to call this a time dimension it really seems more spacial than temporal to me. I didn’t really get it until I found this link that illustrates the concept, and it seems more like the multiple layers of a 3D chess board. My belief is that this is how 3D languages generally operate. But as this was a new concept to me, I thought I’d throw this info out for others.

So Minkolang’s multiple layers are delimited by lines ending in $$$ which I threw onto the end of the Rail code here: #-3o4o#$$$. Now, Minkolang hits the space and falls to first > in <>3N.<> ␉// and proceeds to the right outputting 3. #>couldn’t be allowed to start this line because it would attempt to terminate a Perl6 comment block, so < is used instead of # to balance for SMBF and Brain-Flak. However, this is a Brain-Flak stack swap procedure, so a second set of <> is used after Minkolang Terminates in order to swap back to Brain-Flak’s correct answer.

Labrynth similarly bumps up against the space but it causes Labrynth to moves down in column 1. It then turns down line 2 where it travels down to the 3 hits another wall, causing it to turn south again and hit a ; which causes the 3 to get popped. Then the program continues to the right where 36 gets stored and printed, before finally finding a @ exit. This path is longer than it needs to be, but I found that Prelude would output a nul byte before it’s normal 20 output if the ! was any further to the left than it is now, regardless of the line it appears. So I made it more correct, because I had the space to do so.

Next, Haystack’s routing got changed because / now comes prior to v on line 1 and reflects its path up like Reng. Fortunately, Reng cohabitates rather peacefully. The one hitch was that Haystack’s needle | was a reflector in Reng, so a Reng uses a Befunge like jump (#) over the needle to conclude Reng correctly.

The Befunges continue along line 1 until the v and get directed down and then to the right on the second line to conclude with the same code used before. My sense is that this piece can be golfed down a bit now that fewer languages are attempting to meaningfully traverse the code, but I didn’t need any more walls to bang my head against, so I left it as is.

Finally, Cardinal’s starting point is % which had no particular need to be lumped in to the already dense top two lines. So I moved it down to Python’s string. Its multiple code paths are also now bounded by x’s, which ends the movement of its pointer.

Line 2 &3

The only significant change here is that all of the : got golfed out for one reason or another. Maybe Prelude’s ( needs or maybe it was simple byte count problems – probably both. The other thing is that trigger’s jump code got moved back and rebranded as auaaZ. I had space to fill to meet Befunge’s code path and this seemed best. Also the < following this piece is to balance SMBF’s following >. Finially, the lone near the end of the second line are to maintain 05AB1E’s string. Also, yy on line 3 are just filler characters for Labyrinth.

The Big String Esolangs

With the top two lines resolved, it was time to start digging into the fuller-parsing esolangs, and Pip turned out to have a problem. If you remember we dealt with the curly braces in {std::cout<<37;} by dropping out of the Japt string to let Japt treat this as code. Well, Pip is using the same string syntax and didn’t like this line as code and Pip has very similar string declaration options as Japt. Both use a single ' to declare a one character string, both use the same escape declaration of \ and both will accept " as string identifiers. So it was difficult to make Pip believe this was a string without making Japt believe the same.

It turned out that Japt did have one exploitable difference though - # takes the ascii value of the next character. So, #"` will terminate the Japt/pip string, then tell Japt to take the asci value of ", while telling Pip to start a new string. The " probably could have been a backtick instead, and probably would have been better, but my line of thinking was to use a different string identifier on the inside as another point of string manipulation. So here’s another place where you could save a few bytes down the road.

Next, I had to initiate the Japt string after the curly braces while allowing Pip to remain in a string. I did this with '"` that's a single quote, double quote, and a backtick. For Japt the ' is not in a string and is therefore an indicator to take the next character as a single char string. Pip sees the ' as part of the string and terminates its string with the ". And finally, ` is indicates to both Pip and Japt that another string is beginning which continues throughout the polyglot until the last line where both languages complete happily.

Now, both Japt and Pip worked at this point, but 05AB1E failed because of the use of " caused some error inducing code exposure. Fortunately this one was easy enough to solve by putting another set of " around the whole thing, leaving the set of string manipulations as "`#"\\'*/{std::cout<<37;}/*'"`".

Finally, with the line now looking like this,int main() #/*"`#"\'*/{std::cout<<37;}/*'"`" which Underload had a problem with. The consecutive *’s, were another syntax error so I threw a () in the middle of the *’s to appease it.

The Fragile Esolangs

The big hurdle now was White Space. I won’t go into a ton of detail here because most of the Whitespace solution is built into the explanations already given, and I just glossed over the instances where whitespace forced a few decisions. I’m looking at you Labyrinth. The big change though, is that the actual code to output Whitespace’s answer is on line 2-4 instead of 1-3. This is largely due to Japt’s code exposure in line 1.

Thutu originally had problems with what had been this line: int main() #/*()"`#"\'*/{std::cout<<37;}/*'"`". So, I threw in a linefeed just before the first # to hide all the problems behind a comment indicator and then spammed out a bunch of trailing /’s everywhere else that was code exposed.

At this point I aligned Hexagony and found new problem. The code at the very beginning, which started life as # 1"16" 1 made the + in /+23!@ no longer clear the stack. So, I just removed the + is and found it now output 123. This was easy enough to fix by changing the opening gambit to # 1"16" 2 and golfing the Hexagony piece down to /3!@.

Whirl had some changes, but it was mostly a matter of making sure the right number of leading 1s appeared before the Whirl-Incident line. Incident though had one token that was particularly difficult. I had exactly 3 copies of /* and */.

I initially wanted to just throw *//* any old place in the code to create a 4th copy of each, but Underload saw consecutive *’s again, which was a no go. Ultimately I threw a / on the end of this line int main() /* to make it end in /*/, thinking that I’d make the tokens overlap, but I only succeeded in creating 4 copies of one of the two tokens. Right, right. That’s how that works. Oh well, I’ll just throw a similar / in the final */ to make a 4th there. After this, I replaced a bunch of hexagony no-ops with a 4th copy of several incident tokens in this string on the final line 7LEintndus({})!<>+.

Conclusion

Ok, that's all the detail I have for this massive refactor. I promise not to have so much to write about next time. I actually have no idea if C++ is a good or bad choice for this polyglot, but my sense it opens some options. Hopefully this leads to good things.

Happy coding.

\$\endgroup\$
15
  • 2
    \$\begingroup\$ Looks like g++ requires a .cpp, so I added that to the file extension specific section. Then just had to use run-wrapper.sh to handle it. I'll edit it in. \$\endgroup\$ Commented Jan 30, 2017 at 15:55
  • 1
    \$\begingroup\$ I want to add symbolic brainfuck to this as it's an easy addition, but unicode characters crash python2 - _ - \$\endgroup\$ Commented Jan 31, 2017 at 1:49
  • 1
    \$\begingroup\$ @SnoringFrog I feel the same way about emoji \$\endgroup\$
    – Chance
    Commented Jan 31, 2017 at 2:20
  • 1
    \$\begingroup\$ Also, ** isn't a syntax error in Underload; it just consumes a lot of stack, which I assume wasn't available at the time (likely because you golfed out the colons). You can top up the stack with parenthesized groups or colons before or between them, or sometimes hide the code from Underload by parenthesizing it. \$\endgroup\$
    – user62131
    Commented Feb 1, 2017 at 0:40
  • 2
    \$\begingroup\$ @ais523 In the very early days of C, to save time in cases where it was unnecessary, the preprocessor wasn't run unless the first line started with a #. But if you didn't want your first line to be a preprocessor statement, you would therefore need a way of having the first line start with a # without having it actually do anything, so you had the null directive. I strongly suspect backwards compatibility with code that used this was the rationale for its inclusion in the standard. \$\endgroup\$
    – Muzer
    Commented Feb 1, 2017 at 10:42
37
\$\begingroup\$

3. Minkolang v0.15 (26 bytes)

#>>>>>>>>v
print(1)#>3N.i2

This program prints 1 in Python 3, 2 in Vim, and 3 in Minkolang v0.15

I hope I don't mess things up by introducing a 2d language

Try it online!

Explanation

#                     stops program from moving through time (really does nothing)
 >>>>>>>>             I can't use a space because then the program will move through time
         v            go down
         >            go right
          3N.         Outputs 3 and end program
                      Anything afterward is ignored since program has ended

Vim somehow ignores Minkolang, so that's good

And there really wasn't a problem with Python since it ignores the comments #

Next...

For the next language, I suggest something like ><> since # acts as a reflector (so that the direction will change to left and it will wrap to all the way in the right) so you can add code that can be ignored by other languages

\$\endgroup\$
10
  • 26
    \$\begingroup\$ “move through time” wat? \$\endgroup\$ Commented Dec 6, 2016 at 19:27
  • 7
    \$\begingroup\$ @TùxCräftîñg Minkolang has 3 dimensions (2d = normal, the 3rd one is time). TBH, I don't understand it, it just states that in the explanation on the TIO link \$\endgroup\$
    – user41805
    Commented Dec 6, 2016 at 19:28
  • \$\begingroup\$ @mbomb007 What exactly are you referring to? \$\endgroup\$
    – user41805
    Commented Dec 6, 2016 at 19:35
  • 1
    \$\begingroup\$ @TùxCräftîñg I don't think I can do that \$\endgroup\$
    – anna328p
    Commented Jan 31, 2017 at 20:34
  • 1
    \$\begingroup\$ @wat Hm this took me way too long to understand \$\endgroup\$ Commented Jan 31, 2017 at 20:55
33
\$\begingroup\$

5. Python 2 (35 bytes)

#3N.;n4
print('1'if 1/2else'5')
#i2

This program prints 1 in Python 3, 2 in Vim, 3 in Minkolang v0.15, 4 in ><> and 5 in Python 2.

Try It Online beta!

In Python 2, 1/2 is 0, which is a falsy value, which makes Python print 5. In Python 3, 1/2 is 0.5, which is a truthy value, which makes Python print 1.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I can confirm it works in Minkolang \$\endgroup\$
    – user41805
    Commented Dec 6, 2016 at 19:43
  • 3
    \$\begingroup\$ print('1'if 1/2else'5') breaks on my system without a space between 1/2 and else \$\endgroup\$ Commented Dec 8, 2016 at 8:58
29
\$\begingroup\$

4. ><> (29 bytes)

#>>>>>>>>v;n4
print(1)#>3N.i2

This program prints 1 in Python 3, 2 in Vim, 3 in Minkolang v0.15 and 4 in ><>

Try it Online!

Code ran

#             - change direction to left
            4 - add 4 to stack
           n  - print as a number
          ;   - end the program

Yet another 2D language.

Has no effect on Minkolang as it adds characters after the direction changes, gets ignored by Vim for some reason. # is a comment in Python so no change their either.

\$\endgroup\$
29
\$\begingroup\$

28. Brain-Flak, 280 bytes

#v`16/"<"6/b.q@"(::):::   (22)S#;n4"14"
#>3N6@15o|> ^*ttt*~++~~~%
#=~nJ<R"12";
#[
#`<`|
print((eval("1\x2f2")and (9) or (13))-(0and 4)^(1)<<(65)>>62)or'(\{(\{})(\{}\/^23!@[()])}\{})(\{}\{})'#@46(8+9+9+9+9+=!)=#print(17)#]#echo 21#|/=1/24=x=90/
#8␛dggi2␛` |1|6$//''25  #>say 27#"26

␛ represents a literal ESC character, as usual.

This program prints 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng (tested here), 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in Vim/V, 1 in Python 3

First off, I want to say what a privilege it is to be able to contribute to this challenge. I only heard of code golf a few weeks ago and I have been absolutely hooked ever since. The first thing I did when I found this challenge was try to run the code as is in various languages just to see if I could find anything I could work with. This was back when we were on like #6. I honestly thought this challenge was bonkers impossible, but here we are (#28 Wow!). What I found at the time was that Brain-Flak output the value 2. So I set out to learn it.

Brain-Flak turned out to be pretty great for this kind of challenge because it's fairly easy to learn and it ignores pretty much any characters except (){}[]<>. # also happens to comment anything after it on the same line, so the only part of the last submission that was ever considered for Brain-Flak was print((eval("1\x2f2")and 9 or 13)-(0and 4)^1<<65>>62) which then paired down to ((())()<<>>). So then the plan became adding superfluous parenthesis to what I've come to think of as the python code.

I modified the python bits to parse in Brain-Flak to ((() () ())()()<<()>>) which equates to 2 stacks the first being 5 and the second being 3. After that I'm squaring the 5 with ({({})({}[()])}{}) and adding the result to 3 with ({}{}). This squaring and adding is going on in a string from a Python perspective. I can't claim to understand Python's reasoning here, but I am fairly confident that this string isn't otherwise being evaluated by other languages in a meaningful way, with only a couple exceptions.

Japt, it turns out, interprets curly braces within a string as containing code, but these were easy enough to escape out with \ before each { in this string. But this bloated up the byte count. Such is life.

Prelude was pretty forgiving with all of my parentheses. An earlier comment pointed out that Prelude would have fits with vertically aligned Parentheses and I happened to only create one. Sweet! The ( in the top line lined up with the and (9 in the big line. So I had to add an additional space before the ( in the top line. My assumption here is that the double space was a comment indicator for something, so adding an additional space seemed trivial, and it worked. I should point out that I tried adding a additional spaces in the (9) instead, but Cardinal didn't cooperate.

05AB1E didn't like my first attempt at the Python string being encapsulated in double quotes, but everyone seemed agreeable to using single quotes. Not a big deal there.

Hexagony was the only language left at this point, and I was obviously way past the next hex size threshold, so it was time to get dirty. The /^23!@ is the Hexagony code and I'm super excited about it, because I think it'll make future additions much easier. This little piece can basically be moved anywhere in the python string without busting any code. This is the full string just so we're all on the same page '(\{(\{})(\{}\/^23!@[()])}\{})(\{}\{})'. The / here sets the path of Hexagony from SE ->NW to W-> E down this string, which we have a lot of leeway with. (The preceding \ is to escape / for thutu BTW). My idea here is if you make changes, odds are that you'll end up going through this string at some point and you can slide the Hexagony piece around within the string to catch the code path and send it to the proper conclusion. Just take care not to come between Japt's \ and the {. If you have trouble with this, the @ to the right of the string is just left over from another Hexagony solution, and can be removed without consequence to the other languages. And of course if you happen to catch Hexagony's code path going the opposite direction, you can of course use @!32^\ instead of /^23!@. Also, you may notice that my solution removed the ===2 from the code to keep things under the byte limit. Someone mentioned in here that this was for Hexagony's alignment and I didn't need it anymore.

Finally, here is a little piece of code I found while exploring codegolf that converts a line of text into a Hexagony readable hexagon so you can debug. I'm sure plenty of people know about this, but I hadn't seen it posted here, so it might help someone else too. Fair warning, you have to alter the input to remove the back ticks and carriage returns as well as swap the literal escape for something that takes up normal amount of space to get the code to line things up in a pretty Hexagon.

P.S. While I was writing this out, I realized I had a mistake. I had believed I was clearing Hexagony's memory edge for with the ^, but apparently I can replace it with a no-op to no consequence. That ^ should probably be a + if you try to manipulate this section. I was apparently passing through a + prior to this, but future polyglotters may not be so lucky.

Good Luck!

\$\endgroup\$
4
  • \$\begingroup\$ I was waiting for the rundown and explanation before voting, but the rundown looks good, so I'll vote while waiting for the explanation :-). I assume that all the extra backslashes are to avoid a syntax error in Thutu? Also, interesting approach for where you added your code, which I'm guessing has something to do with Hexagony. It'll be nice to see the full explanation. (Also, welcome to PPCG!) \$\endgroup\$
    – user62131
    Commented Dec 28, 2016 at 4:39
  • \$\begingroup\$ And now I see the explanation; I enjoyed reading it. The "Python code" is actually used by several scripting languages (Python, Perl 5, Ruby), but they all interpret and and or the same way, so your method of commenting the code out in the scripting languages but not Brain-Flak happens to work in all of them. \$\endgroup\$
    – user62131
    Commented Dec 28, 2016 at 8:17
  • 1
    \$\begingroup\$ Thanks @ais523. You mentioned the placement of my code. So, I knew I had to place the brain-flak operators somewhere that was visible to the scripting languages and my initial, incorrect assumption was that it would be easiest on a new line. This didn't work for Retina and I didn't want to deal with both it and the 2D language problems I'd create trying to fix Retina, if possible. I was lucky to stumble into the current placement. \$\endgroup\$
    – Chance
    Commented Dec 28, 2016 at 16:21
  • 2
    \$\begingroup\$ Fantastic answer, and a very thorough explanation! I'm really happy to hear that you enjoy brain-flak. :D \$\endgroup\$
    – DJMcMayhem
    Commented Jan 2, 2017 at 18:59
26
\$\begingroup\$

30. Whitespace, 296 bytes

#v`16/"<"6/b.q@"(: ::T):  ␉␉␉␉ :(22)S#;n4"14"
#>3N6@15o|>␉^*ttt*~++~~~%
#=~nJ<R"12"; ␉
#[␉
#`<`|
print((eval("1\x2f2")and (9)or(13))-(0and 4)^(1)<<(65)>>62)or'(\{(\{})(\{\/+23!@}[()])}\{})(\{}\{})'#46(8+9+9+9+9+=!)=#print(17)#]#echo 21#|/=1/24=x=90/
#8␛dggi2␛␉` |1|6$//''25  #>say␉␉ 27#T222999"26

␛ represents literal escapes.

␉ represents literal tabs.

This program prints 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng (tested here), 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.

Whitespace is another esolang with a limited character set. This one only reads tabs, spaces, and line feeds.

So once we take out all the stuff that Whitespace doesn’t read we’re left with the following code:

[space][space][space][LF]
[space][LF]
[LF]
[LF]
[LF]
[space][space][space][space][space][LF]
[space][space][space][space]

And the code to output 30 is this:

[space][space][space][tab][tab][tab][tab][space][LF]
[tab][LF]
[space][tab]

So the top 3 lines of the existing code were given extra spaces at the end of lines to meet the requirements. Note that line 1’s tabs and trailing space are in the middle of the line to accommodate ><>’s needs.

Line 2’s space was changed to a tab here. This seems to function Identically to a space for the 2D languages, but visually it doesn’t line up anymore. ¯\_(ツ)_/¯

After the instructions to output 30, the game became getting the rest of the necessary spaces and line feeds to do pointless things and compile correctly.

White space happens to have instructions that mark/goto a code location with a label that allows for an arbitrary number of tabs and spaces, so that helped couch the long line’s spaces. It also starts and ends with a line feed, so that helped us up some of the line feeds in lines 3-6.

The final line couldn’t have a linefeed without breaking Retina, so its instructions are to do some arbitrary math and stack manipulation.

Here’s the full code with spaces, tabs, and linefeeds replaced with our notation:

#v`16/"<"6/b.q@"(:[Space]::T):[Space][Space][Tab][Tab][Tab][Tab][Space]:(22)S#;n4"14"[LF]
#>3N6@15o|>[Tab]^*ttt*~++~~~%[LF]
#=~nJ<R"12";[Space][Tab][LF]
#[[Tab][LF]
#`<`|[LF]
print((eval("1\x2f2")and[Space](9)or(13))-(0and[Space]4)^(1)<<(65)>>62)or'(\{(\{})(\{\/+23!@}[()])}\{})(\{}\{})'#46(8+9+9+9+9+=!)=#print(17)#]#echo[Space]21#|/=1/24=x=90/[LF]
#8␛dggi2␛[Tab]`[Space]|1|6$//''25[Space][Space]#>say[Tab][Tab][Space]27#T222999"26[LF]

And here is a commented version of just the Whitespace:

Push 30 onto the stack
[space][space][space][tab][tab][tab][tab][space][LF]

Output the number at the top of the stack
[tab][LF][space][tab] 

Jump to label null if the top of the stack is negative. (it's not)
[LF][Tab][LF]

Label this location as [Space]
[LF][Space][Space][Space][LF]

Add the top two items on the stack and replace them with the result. 
[Tab][Space][Space][Space]

Store the stack.
[Tab][Tab][Space]

Edits: Hexagony turns out to skip over tabs just like spaces, contrary to my previous assertion. @ais523 was kind enough to update @Kenney's Hexagonizer to account for literal escapes and tabs. I had to modify it to correct my prior assertion about tabs being read as no-ops and to replace literal escapes with . because the character is wider than other characters, making the hex slightly misaligned. Here the link.

And this is our corrected current Hex:

          # v 1 6 / " < " 6 /
         b . q @ " ( : : : T )
        : : ( 2 2 ) S # ; n 4 "
       1 4 " # > 3 N 6 @ 1 5 o |
      > ^ * t t t * ~ + + ~ ~ ~ %
     # = ~ n J < R " 1 2 " ; # [ #
    < | p r i n t ( ( e v a l ( " 1
   \ x 2 f 2 " ) a n d ( 9 ) o r ( 1
  3 ) ) - ( 0 a n d 4 ) ^ ( 1 ) < < (
 6 5 ) > > 6 2 ) o r ' ( \ { ( \ { } )
  ( \ { \ / + 2 3 ! @ } [ ( ) ] ) } \
   { } ) ( \ { } \ { } ) ' # 4 6 ( 8
    + 9 + 9 + 9 + 9 + = ! ) = # p r
     i n t ( 1 7 ) # ] # e c h o 2
      1 # | / = 1 / 2 4 = x = 9 0
       / # 8 . d g g i 2 . | 1 |
        6 $ / / ' ' 2 5 # > s a
         y 2 7 # T 2 2 2 9 9 9
          " 2 6 . . . . . . .

Finally, I golfed out some needless characters, mostly added previously to line up Prelude parenthesis and Hexagony hexagons.

Nim’s code is back to echo 21 from echo 5+5+11

Hexagony’s #@46 is now #46

Hexagony’s code is back to /+23!@= from /+23!@

Prelude’s parenthetical alignment of (9) or (13) became (9)and(13)

Well, that’s all I got. Good Luck everyone!

\$\endgroup\$
14
  • 1
    \$\begingroup\$ I think I fixed all the links and added ␛ in places of the space that resulted from my copy pastes. Not sure how to get tabs to be tabs in SE, the code in Tio should disambiguate. I also had to re-create my solution from the instructions in this answer, but somehow ended up with 2 fewer bits... Oops? \$\endgroup\$
    – Chance
    Commented Jan 6, 2017 at 2:35
  • 1
    \$\begingroup\$ Just noticed a mistake in your explanation: carriage return (ASCII 13) is a different character from line feed (ASCII 10). The vast majority of languages (including Whitespace) care about the 10s, not the 13s (and it's assumed that a line break in a PPCG submission is just a single ASCII 10 unless otherwise stated, because the 13s tend to inflate your byte count to no benefit). \$\endgroup\$
    – user62131
    Commented Jan 6, 2017 at 3:43
  • 1
    \$\begingroup\$ Your hexagony explanation image is wrong (prints e23) because of ; after the e when coming up NW after first reflection. The above link works tho...? \$\endgroup\$ Commented Jan 6, 2017 at 6:34
  • 1
    \$\begingroup\$ I have come to the conclusion that the TIO for Hexagony treats tab characters as spaces/newlines. The image you provide of the hexagony program does nothing but exit if you follow it (or put it into TIO, replacing tabs with .s). However, copy the code in the image into TIO, except remove the training .s (not part of the actual code) and all the ␉s. It prints 23. \$\endgroup\$ Commented Jan 6, 2017 at 6:58
  • 1
    \$\begingroup\$ Wow, thanks @MistahFiggins! It looks like I made some deductive errors and propagated them to my explanation. I've corrected the Hexagony explanation, hex diagram, and Hexagonoizer Perl script, as well as cross checked the result against Hexagony directly. Everything should be good now. Good Find! \$\endgroup\$
    – Chance
    Commented Jan 6, 2017 at 16:45
26
\$\begingroup\$

38. C, 804 bytes

#  1"16" 3//v\(@#/;n4"14"
#/*`3 auaaZ<>16/"<"6/b.q@")(22)S#  ␉␉␉␉ 
#yy␉;36!@
# ␉
#=␉>
#[#yy#yy0l0mx01k1k0l0ix0jx0h0h1d111P0eU0bx0b0o1d0b0e0e00x1d0i0fx0g0n0n11x0o0n0cx0c0o0f0c0gx0g0f0h0j0j0i0001k10mx0m0l11111100(^_)
#`<`␉|
print((eval("1\x2f2")and( 9 )or(13 ))-(0and 4)^1<<(65)>>(62))or'(\{(\{})(\{}[()])}\{}\{}\{})'#46(8+9+9+9+9+=!)#1|=/=1/24=x=9[<$+@+-@@@@=>+<@@@=>+<?#>+.--.]/
__DATA__=1#//
#.\."12"*␉
""""#//
=begin␉//
#
#*/␉
#define␉z  sizeof 'c'-1?"38":"37"
#include␉<stdio.h>
int main()  /*/
#()`#`\'*/{puts(z);;}/*'``
$'main'␉//
#-3o4o#$$$
<>3N.<>␉//
#xx
#x%~~~+␉+~*ttt*.x
#xx
=end   #//
"""#"#//
#0]#echo 21#/(\[FAC,1<-#2FAC,1SUB#1<-#52FAC,1SUB#2<-#32FACLEGEREEX,1PLEASEGIVEUPPLEASE)  ap
#_~nJ|#o51\   
#0␛dggi2␛`␉|1|6$//''25  >>>#>27.say# =#print(17)#^_^_7LEintndus({})!<>+]/*///Z222999/(3!@)"26

is a literal tab, a literal ESC character; Stack Exchange would mangle the program otherwise. I recommend copying the program from the "input" box of the TIO link below, if you want to work on it.

Try them online!

Rundown

This program prints 38 in C, 37 in C++, 36 in Labyrinth, 35 in INTERCAL, 34 in Rail, 33 in Incident, 32 in Whirl, 31 in Modular SNUSP, 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng, 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.

Verification

Most of the languages are tested by the test driver shown above. You can test Reng here and Modular SNUSP here; they output 19 and 31 respectively, as required.

Here is my slightly tweaked version of the Incident tokeniser, designed to be a bit less golfed but a bit more useful.

Explanation

I've always loved making little polyglots but never one as big as this; I thought I should probably give it a go!

After @Chance's wonderful C++ answer, C seemed the next logical choice, and given (compared to some previous answers) the relative ease of adding it, I decided to go for it when I had the chance!

I used a very well-known trick to tell the difference between C and C++; the sizeof a character constant is 1 byte in C++ but the sizeof an int (guaranteed to be at least 16 bits) in C. This code should be very portable (except maybe for systems that use bytes with enough bits to fit an int) unless I've made a stupid mistake.

I firstly tried to do a printf with everything inline, but the multiple brackets seemed to be causing issues for Japt, so I made the line simpler, which appeared to fix it.

Next, Cardinal didn't like it, I guessed because of the % in the printf, so I had to solve that one by switching to manipulating strings.

My next attempt, trying to assign a string then change the second byte contingent on the C behaviour, ended up far too long and would have pushed Hexagony onto the next size; I wanted to avoid redoing that by keeping it within the extra characters I had to play with! I needed every byte I could get for this, so I implemented the byte-saving changes suggested by @Chance.

So I golfed that C code down a bit and came up with puts(sizeof'c'-1?"38":"37"); which almost worked, except that Underload was segfaulting, presumably because of the complex expression in the brackets.

Even after removing the extra >> that used to be required to match the << in Perl6, I couldn't get a concise enough way to split out the more complex part of it into a char array assignment. So I ended up looking at using the preprocessor instead.

After a lot of trial and error I found a solution that Retina seemed to like. Prelude which was causing me problems on-and-off all the way through, ended up fixing itself before I got round to looking at why it was breaking (I guess either the brackets or the ! I had in the ternary at one stage, looking at previous answers).

All the while I was patching up the whitespace to get something that Whitespace would like; I found that to be rather easy. Specifically, tab space space space was a very useful combination (the instruction to add the top two items on the stack), since it meant I could add whitespace to lines with no other whitespace without having everything go out of sync (I'm guessing its position in the program means it never actually gets executed so I'm not worried about stack underflows here).

I've now tested Incident, and it works! Many thanks to @Chance and @LliwTelracs, which I've just realised is NOT a Welsh name, for helping me get to grips with it. See this syntax highlighting. I have removed the ; token that was appearing before the #yy token. I did this by simply adding an extra ; after the gets statement (my previous attempt involved replacing s (which now appears much more in the C program than it did in the previous one) in the "detokenising" string with a ;, but it turned out I was actually a character short for Hexagony (thanks @Chance), so after attempts to add an extra character to this last line failed, I just changed it back and added the extra semicolon elsewhere).

I have also tweaked the whitespace a little to change some other tokens to make some attempt at centring, to re-tokenise Tab Linefeed (by moving the tab at the end of the #include line to in the middle, thus making three tokens), and to de-tokenise the triple-space token by moving one space in the define line.

Finally, a day after initial submission, I decided to get to the bottom of the scary preprocessor warning that gcc produced (and which made Clang fail). I determined that the reason the first line worked at all is because it's the output from the preprocessor that provides debug info like original filenames and line numberings. They didn't like the first "2" on the first line, because this meant "returning from an included file into the given file", and obviously that's impossible given there haven't been any included files. After changing it to a "1" (start normal header) made a few too many languages choke, I changed it to a "3" (start internal component header), which broke only Hexagony, since it was now relying on the 2. So at the start of the Hexagony code I added an open bracket ( to decrement the 3 to a 2, then a close bracket ) after the end (@) of the hexagony code to satisfy Retina, Prelude and Underload which all expected matching brackets. Re-testing Reng and Modular SNUSP produced no issues, and the Incident tokens looked right, so I had now fixed it! I've tested it on a variety of exotic architectures and it appears to work. I know it's not important for a code golf, and I won't mind if future submitters have to break this again to keep within a byte count or whatever (or if anyone's already started based on this solution and doesn't want to change theirs too much), but there is one good reason I've done this - TIO's Objective-C compiler only supports Clang, so this'll be very useful if anyone wants to add that!

Bear in mind I've never used most of these languages, I hope my success encourages more newcomers to give this a try!

\$\endgroup\$
13
  • \$\begingroup\$ @LliwTelracs Huh, the C program linked by Chance in his answer had a different output for the list of tokens: ;#yy;#yy#yy0l0m1k1k0l0i0j0h0h1d0e0b0b0o1d0b0e0e1d0i0f0g0n0n0o0n0c0c0o0f0c0g0g0f0h0j0j0i1k0m0m0l^_()z z()()z; ^_^_ \$\endgroup\$
    – Muzer
    Commented Feb 1, 2017 at 16:49
  • \$\begingroup\$ The error was that I was copy pasting the value to my program so it couldn't recognize the tabs or escapes \$\endgroup\$ Commented Feb 1, 2017 at 17:25
  • \$\begingroup\$ @LliwTelracs Just trying to figure out the tokenisation myself, it looks like I've now got a semicolon appearing three times. I could add an extra one except that I don't think I can spare the byte as that'll misalign Hexagony. Hmm... \$\endgroup\$
    – Muzer
    Commented Feb 1, 2017 at 17:57
  • 1
    \$\begingroup\$ Incident works! \$\endgroup\$
    – Muzer
    Commented Feb 1, 2017 at 21:13
  • 1
    \$\begingroup\$ @Chance I've just been looking at how that first line is valid in the C Preprocessor, it looks like it's the output from the Preprocessor used for debug info etc. It means "now returning (2) to file with name "16" line 1". I think it's the 2 that makes Clang choke (and gcc warn) since it never went into any files in the first place, so there's nothing to return from. When I get the chance I might experiment with changing it to something else to make it compile in Clang too. See gcc.gnu.org/onlinedocs/cpp/… \$\endgroup\$
    – Muzer
    Commented Feb 2, 2017 at 12:07
26
\$\begingroup\$

2. V (11 bytes)

print(1)#i2

This program prints 1 in Python 3, and 2 in V.

Just to get the ball rolling and to throw my favorite language into the mix early on. :)

It's a very straightforward answer.

print(1)#

just so happens to be a NOP in V. (lucky for me) Then i2 enters insert mode and inserts a '2'. You can try V online here

Of course, in python

print(1)

prints '1', and

#i2

is a comment.

\$\endgroup\$
10
  • 3
    \$\begingroup\$ Is this V or Vim? The interpreter you linked to is technically "V". \$\endgroup\$
    – mbomb007
    Commented Dec 6, 2016 at 19:22
  • 2
    \$\begingroup\$ Not really, just edit the title in the answers. \$\endgroup\$
    – mbomb007
    Commented Dec 6, 2016 at 20:12
  • 1
    \$\begingroup\$ @mbomb007 A literal ESC character will do it (which is why I had to use one in my submission). \$\endgroup\$
    – user62131
    Commented Dec 7, 2016 at 0:05
  • 2
    \$\begingroup\$ Note for those testing this out: You need to make sure you don't have a cliipboard carried over from the previous Vim session. \$\endgroup\$
    – Riking
    Commented Dec 9, 2016 at 7:14
  • 1
    \$\begingroup\$ I don't have Vim installed but I have Vi in which the i in print triggers insert mode - according to the man pages r is replace a character in both languages, why does Vim ignore that first i but not Vi? Thanks! \$\endgroup\$ Commented May 30, 2017 at 1:34
25
\$\begingroup\$

20. Prelude, 167 bytes

#v`16 "<" 6/b0\ .q@#;n4"14""
#>3N9@15o|R"12"*^*ttt*~++%
#=|
print((1/2and 9 or 13)-(0and+4)^1<<65>>62);#35(99999+++++!) =#;print(17)
#       ~nJ<
#
#gg99ddi2` |1|1+6

Literal ESC characters in the same place as in the previous submissions (between the # and g, and between the 2 and `, on the last line), because you can't take Vim out of insert mode with printable characters.

This program prints 20 in Prelude, 19 in Reng (testable here), 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in Vim/V, 1 in Python 3, and a partridge in A Pear Tree.

The existing code pretty much cancels itself out in Prelude, consisting only of while loops with falsey arguments and some stack manipulation on stacks we don't care about. Even better, there's a spot in the code that's a comment in all the languages that have them (between the # and =# of the previous submission). The hard part of fitting Prelude into this was generating numbers with only one stack and without blowing up the byte count. This program uses a loop that adds 45 to every stack element and outputs it as ASCII, thus by placing a 5 above a 3 on the stack, we get 20 as output. (Neatly, 20 is an easier number to output than 19 is in Prelude, so answer 19 being posted actually helped me a bit.)

\$\endgroup\$
4
  • \$\begingroup\$ Prelude should be fairly easy to work into future programs. Some advice for anyone it may happen to cause trouble to: don't let parentheses line up vertically; make sure you don't allow exclamation marks outside parentheses; and once you've placed digits outside parentheses, don't place more parentheses further right on the same line. The gap which I put the Prelude program into is still open, and looks like it might be a fruitful place for other 1D languages to go (Prelude's sort-of 1½D, and acts more like a 1D language in this program). \$\endgroup\$
    – user62131
    Commented Dec 8, 2016 at 6:53
  • \$\begingroup\$ Nice, beat me to the punch with Prelude :) I actually think ASCII-only V might be possible with :%s replace, but even then it's a little tricky (and V is annoying to test) \$\endgroup\$
    – Sp3000
    Commented Dec 8, 2016 at 7:24
  • \$\begingroup\$ If you use a : to start a command in vim, you're gonna need a carriage return, which also happens to be unprintable. :/ \$\endgroup\$
    – Zwei
    Commented Dec 8, 2016 at 9:07
  • 8
    \$\begingroup\$ +10000000000 for a partridge in A Pear Tree. But does it print 5 GOLD in RINGS? \$\endgroup\$ Commented Dec 12, 2016 at 1:32
25
\$\begingroup\$

100. brainbool, 2953 bytes

#16  "?63(o?23!*# #@"/*\DZZCv;'[af2.q]PkPPX)\('#CO"14"; */
#/*0|7//```"`  [>.>.])[-'][(>77*;,68*,@,1',;# l1011)(22)S\4n;iiipsddpsdoh coding:utf8ââââ(1P''53'S^'????!?!??!??!!!!???!?!??!!?!?!!!!!?!!!!?????!????????????????????!) (qx
#>â
# 36!@â`  e++++++::@ 
#~
#y
#`<`
#<<<#>>]}}+-[.+..]+-+<[<<.>>x>-]>[
#{
#x}
#2""/*\*
#=x<R+++++[D>+++++++q   L+++<-][pPLEASE,2<-#2FAC,2SUB#1<-#52FAC,2SUB#2<-#32FACREADOUT,2PLEASEGIVEUPFACs]>@@+.---@.>][
#x%+>+=ttt Z_*.
#D>xU/-<+++L
#R+.----\   \).>]4O6O@|
#[#[(?2?20l0v01k1kMoOMoOMoOMoO MOO0l0ix0jor0h0h1d111x0eU0y0yx0moO1d0y0e0e00m1d0i0fx0g0n0n11MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmOoMOo0moo0n0tx0t0moO0f0t0gOOM0g0f0h0j0j0i0001k1x0vx0v0l111111^_0 )0\\
[  "]56p26q[puts 59][exit]" ,'\[999'];#/s\\/;print"24";exit}}__DATA__/
###x<$+@+-@@@@=>+<@@@=>+<?#d>+.--.<!\
'(wWWWwWWWWwvwWWwWWWwvwWWWw WWWWWWWWwWW/"78"oo@WWwWWWWWWWwWWWWWWWWwwwwvwWWWwWWWWwvwWWwWWWwvwWWwWWWwvwWWwWWWw              (([5]{})))â\';';print((eval("1\x2f 2")and 9or 13<< (65)>>65or 68)-(0and 4)^1<<(65)>>62)or"'x"or' {}{}{}{}({}<(((((()()())){}{})){}{})>)(({})5){}x{(x<(<()>)({})({}<{}>({}){})>){({}[()])}}({}){}({}()<()()()>)wWW no no no no no no no no no no no no no no no no no no no no no no no no no no no no no no os sp '#}#(prin 45)(bye)46(8+9+9+9+9+=!)((("3'3)))"'a'[[@*3*74[?]*]*(<*.*\>]xxxxxxxxxxxxx)'# \\
__DATA__=1#"'x"
#.;R"12"'
###;console.log 39;'(******* **********819+*+@[*99[?]*]***|!)'
#\\
""""#\
' ( <><        (          )>  ){ ({}[()]  )}{\';      a=$(printf \\x00    );b=${#a};#\\
" }"';           ((   ( (';case "{"$ar[1]"}"${b} in *1)echo 54;;*4)echo 78;; *1*)echo 50;;*)echo 58;;esac;exit;# (((('))))#\
=begin
#p             +555/2+55x%6E2x
;set print "-";print 89;exit#ss 9
utpb now 70 dollar off!
utpb has been selling out worldwide!
#9999 9 seeeemPaeueewuuweeeeeeeeeeCis:ajjappppppp😆😨😒😨💬95💬👥➡
👋🔢🌚🌝🌝🌚🌚🌚🌚🌚

set ! 57
set ! 51
More 91 of thiset of re9
How much is it*/
#if 0
.int 2298589328,898451655,12,178790,1018168591,84934449, 12597
#endif//*
#1"" //*
#include<stdio.h> 
#defineâ x(d)â#d
#define u8 "38\0 "
main ( ) {puts( sizeof (0,u8)-5?u8"67":*u8""?"37":     x( 0'0  "'\"")[9]?"75":'??-'&1? "79":"77");"eg5""6 27""e ' Zing  ";}//*/
#if 0
#endif//* --... ...--
/*/
p=sizeof("9( 999 99\"    ); print'(''72'')';end!"            );main( ){puts(  "92");return(9-9+9 -9);}
#if 0â
#endif//* rk:start | print: "69" rk:end<(9    >5b*:,1-,@
print 61
#}
disp 49 ;9;
#{
}{}<>
$'main'3
#-3o4o#$$$
#<T>"3"O.</+++++++>/+++<-\>+++.---.
#<<<#>>> /
reg end="";print(85);reg s#++++++++++++++++++++++++++++++++++++++++++++++++++++++++.-.
=end
;"""#"#xxxxxxxy"78"\++++>/<~#class P{        function:Main(a:String[] )~Nil{83->Print();} }
#}pS9^7^8^MUOUOF@:8:8\\
#s|)o51~nJ;#:p'34'3  \=#print(17)#>27.say#]# print(47) #]#echo 21#fwwwwwWWWwWWWWWwWWWWWWWwWWWWWWWWWwWWWWWWWWWWWWWWWwWWWWWWWWWWWWwvm>++++
#s8âdggi2âM`|$//''  1$6~-<~-<~-<<<~-COprint ("65")#asss^_^_#
#9 "25"  +/ *///X222999686#

VIP score (Versatile Integer Printer): .002953 (to improve, next entry should be no more than 3042 bytes)

Rundown

This program prints 1 in Python 3, 2 in V/Vim, 3 in Minkolang, 4 in ><>, 5 in Python 2, 6 in SMBF, 7 in Japt, 8 in Retina, 9 in Perl 5, 10 in Befunge-93, 11 in Befunge-98, 12 in Fission, 13 in Ruby, 14 in Turtlèd, 15 in Haystack, 16 in Pyth, 17 in Julia, 18 in Cardinal, 19 in Reng, 20 in Prelude, 21 in Nim, 22 in Underload, 23 in Hexagony, 24 in Thutu, 25 in Pip, 26 in 05AB1E, 27 in Perl 6, 28 in Brain-Flak, 29 in Trigger, 30 in Whitespace, 31 in Modular SNUSP, 32 in Whirl, 33 in Incident, 34 in Rail, 35 in INTERCAL, 36 in Labyrinth, 37 in C++03, 38 in C99, 39 in CoffeeScript, 40 in Minimal-2D, 41 in brainfuck, 42 in evil, 43 in reticular, 44 in alphuck, 45 in PicoLisp, 46 in Cubix, 47 in Lily, 48 in Deadfish~, 49 in Octave, 50 in Bash, 51 in Assembly, 52 in COW, 53 in Shove, 54 in Zsh, 55 in Brain-Flak Classic, 56 in dc, 57 in Wise, 58 in Ksh, 59 in Tcl, 60 in Moorhens, 61 in S.I.L.O.S, 62 in Grass, 63 in Brian & Chuck, 64 in Agony, 65 in ALGOL 68, 66 in Surface, 67 in C11, 68 in Python 1, 69 in rk-lang, 70 in Commercial, 71 in what, 72 in Fortran, 73 in Morse, 74 in Archway, 75 in C++11, 76 in Trefunge-98, 77 in C++14, 78 in dash, 79 in C++17, 80 in Klein 201, 81 in Klein 100, 82 in Brain-Flueue, 83 in Objeck, 84 in Klein 001, 85 in zkl, 86 in Miniflak, 87 in Alice, 88 in PingPong, 89 in gnuplot, 90 in RunR, 91 in Cood, 92 in C89, 93 in Set, 94 in Emotinomicon, 95 in Emoji, 96 in EmojiCoder, 97 in Cubically, 98 in Archway2, 99 in 99. 100 in brainbool

Verification

Try it online! Languages not available on TIO:

  • Japt, 7 online.
  • Reng, 19 online.
  • Deadfish~, 48 local.
  • Moorhens, 60 local. use moorhens.py from the v2.0-dev branch
  • Morse, 73 local
  • Archway, 74 local
  • Trefunge-98, 76 local. Use -d 3 -v 98 for Trefunge-98.
  • Objeck, 83 local
  • zkl, 85 local
  • PingPong, 88 local
  • RunR, 90 local
  • Cood, 91 online
  • Set, 93 online
  • Emotinomicon, 94 online
  • EmojiCoder, 96 online
  • Archway2, 98 local I can not test Archway2 because I don't have the proper C compiler, however stasoid has confirmed it works in archway2

Explanation

I can't believe we've made it to 100 languages. I would just like to take the time to thank everyone thats been involved in this process. Its been a fun ride and I hope to add a 100 more with you guys.

Brainbool has been in my eye for a while. However since brainbool can only output two numbers, 1 and 0 I have not been able to add it until now (I wasn't around for 10 and 11).

Brainbool is just like brainfuck, except instead of wrapping at 256 it wraps at 2. Brainbool also does not have a - because it is redundant with the +. Our brainbool code to output 100 is fairly simple:

+.+..

In order to mask the outputs for brainfuck we add a loop and a minus:

+-[.+..]

Now all thats needed is to find a place for the code to go. My place of choice was the first + at the top level of the brainfuck code on line 8. To substitute in the plus we added our code and a +-+ which acts as a + in brainfuck and a noop in brainbool.

+-[.+..]+-+

Cubix

I put my code before the Cubix capsule causing a mirror to move into the path of the pointer. In order to fix this I moved the capsule a couple of steps forward in front of the offending mirror and all was well.

Surprisingly nothing else broke not even the notoious incident.

\$\endgroup\$
7
  • \$\begingroup\$ Actually, brainbool can output aribtrary text. If you pass it the -b argument, it will build 1s and 0s into bytes and then outputs as characters. \$\endgroup\$
    – Pavel
    Commented Jul 30, 2017 at 22:18
  • 1
    \$\begingroup\$ @WheatWizard I confirm that it works in Archway2. \$\endgroup\$
    – stasoid
    Commented Jul 31, 2017 at 1:06
  • 1
    \$\begingroup\$ Congrats! I notice the VIP score just dropped under 0.003 as well. \$\endgroup\$ Commented Jul 31, 2017 at 1:26
  • 1
    \$\begingroup\$ I have to confess, back when you originally posted about adding this for 100/101, I didn't actually think we'd ever get here. This is pretty dang cool. \$\endgroup\$ Commented Jul 31, 2017 at 14:47
  • 1
    \$\begingroup\$ @stasoid I'm working on getting Archway on TIO, just FYI. \$\endgroup\$
    – MD XF
    Commented Jul 31, 2017 at 17:11
24
\$\begingroup\$

65. ALGOL 68 (Genie), 1634 bytes

#16  "(}+?23!@)-("//*\Dv;'[af2.q]PkPPX'#CO)"14";n4
#/*0|7//```"`   [-'][!(>77*,;68*,@;'1,@10␉␉11)(22)S␉␉(1 P''53'S^'q
#>␉
# 36!@␉`
#
#_>++++.>.}+?
#`<`
#<]}} +<[<.>>-]>[
#{
#z}
#
#=x<R+++++[D>+++++++59L+++<-][pPLEASE,2<-#2DO,2SUB#1<-#52DO,2SUB#2<-#32DOREADOUT,2PLEASEGIVEUPFACiiipsddsd4O6O@oh]>@@+.---@.>][
#x%+>+=ttt Z_*.
#D>xU/-<+++L
#R+.----\).>]|
#[#[(?2?20l0v0x1k1kMoOMoOMoOMoOMOO0l0ix0jor0h0h1d111x0eU0yx0y0moO1d0y0e0e00m1d0i0fx0g0n0n11MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmOoMOo0moo0n0tx0t0moO0f0t0gOOM0g0f0h0j0j0i0001k1x0vx0v0l111111^_00)
[ "]56p26q[puts 59][exit]" ,'\[' ];#/s\\/;print"24";exit}}__DATA__/
#
###x<$+@+-@@@@=>+<@@@=>+<?#d>+.--.

#
'(((p\';a=a;case $argv[1]+${a:u} in *1*)echo 50;;*A)echo 54;;*)echo 58;;esac;exit;';print((eval("1\x2f2")and 9or 13)-(0and 4)^1<<(65)>>62)or"'x"or'{}{}{}{}({}<(((((()()())){}{})){}{})>){(<{}(({}){})>)}{}({}())wWWWwWWWWwvwWWwWWWwvwWWWwWWWWWWWWwWWWWwWWWWWWWwWWWWWWWW li ha '#}#(prin 45)(bye)46(8+9+9+9+9+=!)((("'3)3)3)"'
__DATA__=1#"'x"
#.;R"12"'
###;console.log 39
""""
=begin
<>{nd
#sseeeemPaeueewuuweeeeeeeeeeCis:ajjap*///;.int 2298589328,898451655,12,178790,1018168591,84934449,12597/*
#define p sizeof'p'-1?"38":"37"
#include<stdio.h>
main ( ){puts(p);}/*
print 61
#}
disp 49;
#{
}<>
$'main'3
#-3o4o#$$$
#<T>"3"O.s
=end
"""#"
#}
#s|o51~nJ;#:p'34'3\=#print (17)#>27.say#]#print(47)#]#echo 21# xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi ax fwwvwWWWwWWWWwvwWWwWWWwvwWWwWWWwvwWWwWWWwvwWWwwwwwwwwwwwWWWwWWWWWwWWWWWWWwWWWWWWWWWwWWWWWWWWWWWWWWWwWWWWWWWWWWWWwvm 
# sss8␛dggi2␛`|$// ''25  16*///~-<~-<~-<<<~-XCOprint("65")#s^_^_2229996#

VIP score (Versatile Integer Printer): .005949 (to improve, next entry should be no more than 1710 bytes)

Try it online!

Rundown

This program prints 65 in ALGOL 68, 64 in Agony, 63 in Brian & Chuck, 62 in Grass, 61 in S.I.L.O.S, 60 in Moorhens 2.0, 59 in Tcl, 58 in Ksh, 57 in Wise, 56 in dc, 55 in Brain-Flak Classic, 54 in Zsh, 53 in Shove, 52 in COW, 51 in Assembly, 50 in Bash, 49 in Octave, 48 in Deadfish~, 47 in Lily, 46 in Cubix, 45 in PicoLisp, 44 in alphuck, 43 in reticular, 42 in evil, 41 in brainfuck, 40 in Minimal-2D, 39 in CoffeeScript, 38 in C, 37 in C++, 36 in Labyrinth, 35 in INTERCAL, 34 in Rail, 33 in Incident, 32 in Whirl, 31 in Modular SNUSP, 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng, 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.

Verification

Most languages can be tested with the test driver above, but 6 languages have to be tested locally.

  • Reng can be tested to output 19 here.

  • Modular SNUSP can be tested to output 31 here.

  • Incident was verified to test 33 via manual balancing of tokens.

  • Deadfish~ can be tested to output 48 locally, using this interpreter. Note that Deadfish~ takes the polyglot to be fed on stdin, but and prints a number of >> prompts to standard output, which are n unavoidable consequence of running any Deadfish~ program.

  • Moorhens 2.0 can be tested to output 60 using this interpreter.

ALGOL 68

ALGOL is probably the least known of the four high-level programming languages from the early days of programming - the remaining languages of this nebulous distinction being COBOL, FORTRAN, and Lisp. ALGOL was better known in academic and mathematic circles at the time, but is today best known for its huge influence on modern languages. In fact most modern, practical languages can be described as “Algol-like,” not the least of which is C, which of course has its own lineage of influences and derivatives.

I’m pretty excited to include ALGOL because it’s another major stepping stone in computer history that we get to add to this monument we call a polyglot. That’s cool stuff.

ALGOL68 is the latest of the three major ALGOL specifications, the others being ALGOL60 and ALGOL58. Interestingly, the specification doesn’t have a fixed syntax, meaning that the tokens are defined, but not the spellings. This makes the language highly interpreter dependent because any given interpreter may use a different symbol to initiate a comment block for example. The specification describes the ¢ as initiating a comment block. But because ¢ isn’t among the base 127 ascii codes it understandably doesn’t see much use as the comment indicator among the available interpreters. Well it turns out that the Genie interpreter spells ¢ as #, which is all the opening we need to get past character 1 and make a polyglot.

Genie in fact has three comment syntax options, the other two being co and comment, both of which are specified as being written in bold. Yeah, bold. If we use italics, well that’s a variable. Genie solved that for us again by spelling bold in all caps. And since CO isn’t in the polyglot anywhere, we’ve got an easy method of hiding the polyglot from the parser. If down the road CO is needed for a language, we can switch to the more verbose COMMENT syntax.

There are no line comments in ALGOL - they’re all block style, which means they need to be terminated. Given the initial state of the polyglot, our ALGOL block comment is opened immediately and is terminated near the end of line 1 because Turtlèd is similarly using # as a jump token. Turtlèd very fortunately doesn’t have a problem walking through the C and O characters so in line 1 we can just insert CO immediately after the second # to initiate a fat block comment for ALGOL68.

From here we just have to place COprint("65") somewhere. I chose the last line because I preferred to finish out the line with another # comment and I didn’t want the comment to terminate at the # at the beginning of the last line. So we follow up our ALGOL print statement with #s and a # as the last character in the polyglot. The s in #s is for alphuck to balance out the p in print.

Thanks to @ais523 for opening up the end of the polyglot with answer 59 and making all this possible.

SMBF

We added a different character to the end of the polyglot to terminate ALGOL’s final comment, and SMBF was previously reading the last character for its answer. To remedy this, I had to change SMBF to read the second to last character by changing this code on line 8 [.>-] to this [<.>>-]. This is an SMBF private code block since BF’s MP is at 0 when the loop is initiated.

Trigger

At this point, I noticed some weird behavior with SMBF and it had to do with the relationships between these code segments ad the end of the polyglot.

• Incident’s jump destination: ^_^_

• Trigger’s Jump destination plus answer: X222999

• ALGOL68’s answer: COprint("65")#s

ALGOL’s answer tokenized a couple Incident tokens within its code segment, so ALGOL’s code had to go prior to Incident’s code segment. ALGOL also caused a prelude alignment issue if it went first in the order so it had to go second or third. SMBF meanwhile had an inexplicable failure when Incident’s code went last, so Incident had to go first or second. Well, I realized this was an introductory logic problem that appeared unsolvable, so I set out to make the inexplicable more… plicable.

After walking through SMBF I found that the problem with having ^_^_ at the end was due to Wise. Wise’s code ( ~-<~-<~-<<<~-) isn’t hidden behind a non-executing loop, unlike most of the polyglot. But there’s no SMBF print codes involved in Wise’s code. It was just changing memory values. It seemed innocuous. So what was the problem then? It was that darn SM in front of the BF.

Wise’s code is changing the characters in the code about to be executed, and can you guess what the ascii value neighbor of ^ is? It’s ]. Wise was putting a SMBF loop terminator at the end of the polyglot, causing SMBF to fall into an infinite loop. That’s bad mojo.

After some thought I took the 0 byte solution to the problem and separated Trigger’s jump destination (X) from its answer (222999) and ended the polyglot thusly: ~-<~-<~-<<<~-XCOprint("65")#s^_^_2229996#. This only works because no character appears consecutively following Trigger’s jump that isn’t Trigger’s answer.

Wrapping up

That's all the major changes this round. I did make a minor change to cut the much discussed c in line 1, but that's it for purely golfing changes.

Good Luck!

Incident Report

#<q>"3"O.s became #<T>"3"O.s because detokenizing T instead of q was more efficient at balancing

<>{ became <>{nd to detokenize nd and {␊

Put a space between }} and + in #<]}} +<[<.>>-]>[ to detokenize }}+ more cheaply.

\$\endgroup\$
22
+50
\$\begingroup\$

27. Perl 6, 235 bytes

#v`16/"<"6/b.q@"(::):::  (22)S#;n4"14"
#>3N6@15o|> ^*ttt*~++~~~%
#=~nJ<R"12";
#[
#`<`|
print((eval("1\x2f2")and 9 or 13)-(0and 4)^1<<65>>62)#@46(8+9+9+9+9+=!)=#print(17)#3]#echo 21#===2|/=1/24=x=90/
#8␛dggi2␛` |1|6$//''25  #>say 27#"26

␛ represents a literal ESC character, as usual.

This program prints 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng (tested here), 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in Vim/V, 1 in Python 3, and (as it's Christmas) a partridge in A Pear Tree.

The syntax highlighting that Stack Exchange produces for this answer is completely wrong. #`< is one of Perl 6's many multiline comment markers, and ends at #>, thus the only code that actually runs in Perl 6 is the very simple say 27. I chose this particular comment marker because <> aren't a matching pair in most languages, and thus the unmatched < won't break languages, such as Retina, that attempt to parse it.

I'm not entirely sure how the Hexagony works any more. When it broke, I changed one of the characters it was using from a + to a 0 to see if it was being hit; turns out it was, and turns out this fixed the program, but I'm not sure why (I know it broke due to a # in the line of execution, but it's unclear why removing the + fixes things). (The character in question is also parsed by Thutu, but luckily this doesn't make a difference to the functioning of the Thutu program, as at that point in the program, anything that isn't preceded by an = is copied literally into the working string.) Note that the 0and+4 from a previous line became 0and 4, to make it one character shorter from Hexagony's point of view (Hexagony doesn't see spaces); this is to compensate for the #| on a previous line becoming #`<`|, which is one character longer from Hexagony's point of view (because it doesn't see backquotes either). Note that the code's now only five bytes away from expanding the Hexagony side length and breaking everything about the current Hexagony code. I'd recommend doing this anyway and just redoing the Hexagony section of the code; it'll probably be easier, rather than harder, to fit everything in after an expansion.

Some other languages changed too, mostly to add enough robustness that I could fit arbitrary code in on the last line. $// is a comment marker in Japt that allows spaces later on the line, making the added program less fragile in Japt (meanwhile, // breaks if there are any closing parentheses later on the line, and space is a sort of closing parenthesis in Japt). A pair of spaces is a comment marker in Pip, meaning that the Pip code can be substantially simplified here. This also means that we can simplify the 05AB1E down to a trivial "26. Retina needs the fifth line to be a legal regex that's good at matching things (the trailing | is thus for Retina); it parses differently from the corresponding line in the previous entry, but in a way that's just as suitable. The Cardinal is also very slightly simpler than in previous entries, but this is just pure coincidence with how everything lines up vertically, and the change is to code that didn't do anything anyway.

Assuming you redo the Hexagony (you'll probably have to), there are safe places to add code on all of the last three lines: the 3 in #3]# is only for Hexagony (and easily changed); the space between the # and " on the final line is ignored by the vast majority of languages; and nothing's really parsing the end of the fifth line other than Retina. (There are plenty of other places where code can be added, too, but these are probably the most convenient.)

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I accidentally downvoted this answer and noticed I downvoted when i noticed my rep's gone down by 1. Can you edit the answer so I can upvote? :D \$\endgroup\$
    – betseg
    Commented Dec 25, 2016 at 9:37
  • 6
    \$\begingroup\$ @betseg: I added a bit more discussion of the Hexagony, just for you. \$\endgroup\$
    – user62131
    Commented Dec 25, 2016 at 12:37
  • 2
    \$\begingroup\$ Congrats on the bounty! I wanted to get this post moving again :P \$\endgroup\$
    – FlipTack
    Commented Dec 25, 2016 at 15:26
  • \$\begingroup\$ I'd been planning to continue it for ages, it was just a case of trying to find the time. (I'd actually made a failed attempt at Perl 6 a while back, earlier in the chain, and didn't post it because it didn't work. Luckily, I learned from the mistakes and it works this time.) \$\endgroup\$
    – user62131
    Commented Dec 25, 2016 at 21:19
22
\$\begingroup\$

35. INTERCAL (C-INTERCAL), 631 bytes

#v`16/"<"6/b.q@"(: ::Q):  ␉␉␉␉ :(22)S#;n4"14"
#>3N6@15o|>␉^*ttt*~++~~~%
#= >␉1#v#v0l0mx01k1k0l0ix0jx0h0h1d111P0eU0bx0b0o1d0b0e0e00x1d0i0fx0g0n0n11x0o0n0cx0c0o0f0c0gx0g0f0h0j0j0i0001k10mx0m0l11111100(^_)
#[␉
#`<`|
print((eval(" 1\x2f2")and(9)or(13))-(0and 4)^1<<(65)>>(62))or' (\{(\{})(\{}[()])}\{}\{}\{})'#46(8+9+9+9+9+=!)#1111|=/=1/24=x=9[<$+@+-@@@@=>+<@@@=>+<?#>+.--.]/
__DATA__=1#//
#.\."12"␉*
""""#//
=begin␉//
$'main'//
#-3o4o#␉
=end   #//
"""#"#//
#0]#echo 21#/ (\[FAC,1<-#2FAC,1SUB#1<-#52FAC,1SUB#2<-#32FACLEGEREEX,1PLEASEGIVEUPPLEASE) a
#   +/Jn~
#8␛dggi2␛`␉|1|6$//''25  >>>#>27.say# =#print(17)#$nd^_^_.]Q222999/+23!@1#"26

is a literal tab, a literal ESC character; Stack Exchange would mangle the program otherwise. I recommend copying the program from the "input" box of the TIO link below, if you want to work on it.

Try them online!

Rundown

This program prints 35 in INTERCAL, 34 in Rail, 33 in Incident, 32 in Whirl, 31 in Modular SNUSP, 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng, 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.

Verification

Most of the languages are tested by the test driver shown above. You can test Reng here and Modular SNUSP here; they output 19 and 31 respectively, as required. I tested Incident locally on my own system, using the official interpreter.

Note that I added a few changes to the test driver in order to make it easier to spot hidden characters; various NUL bytes had crept into the program's output in certain languages. I've decided that this probably isn't a problem, because a) a wide range of submissions have been doing it, and b) the Befunge interpreters seem to be adding extra NUL bytes even though nothing in the program implies that (unless I've missed something), so it must have been going on for ages and is probably part of how the interpreter works. (Note that the languages that still output NUL bytes – the Befunges and Minkolang – haven't had their code changed for this submission.)

The previous Rail submission exits via crash, which is disallowed, but this is easily fixable (by adding a # at the end of the Rail program and adjusting the Hexagony to match) and so I didn't consider it a major problem. The Rail in this solution exits correctly.

Explanation

How the INTERCAL code works

INTERCAL parses the entire program. However, syntax errors are a runtime thing in INTERCAL, not compile-time, and this is often used to create comments. (If a syntax error attempts to execute, it'll crash the program with error ICL000I, contrary to what Wikipedia incorrectly claims. But if you can prevent it executing somehow – and INTERCAL has a lot of ways to prevent commands running – it'll quite happily not execute without causing a problem.)

As such, we can prevent garbage at the end of the file running simply by exiting the program explicitly first (something that's required anyway, because INTERCAL crashes if the end of the program is reached without an explicit exit command). Handling the start of the program is more interesting, and exploits a parser bug. You can write something like DO %20 READ OUT #8 to output VIII with a 20% probability (and otherwise do nothing). As far as I can tell, C-INTERCAL parses the lone % on the second line as indicating a 0% probability for the first command to run, and thus ends up consistently not running it every time. (I'm not sure why it parses it like that, but looking at the compiled code shows it generating a random number and comparing it to 0.)

Here's how the INTERCAL program looked before fitting it around the rest of the polyglot:

DO,1<-#2
DO,1SUB#1<-#52
DO,1SUB#2<-#32
DOREADOUT,1
PLEASEGIVEUP

This is fairly simple: instantiate a 2-element array; set the elements to 52 and 32 (decimal) respectively (INTERCAL's string encoding is best left unmentioned; I've forgotten how it works and had to do various experiments to figure out why these numbers encode 35); read it out to standard output; and exit the program. I added an additional PLEASE at the end in order to terminate the GIVE UP statement, starting a new statement for the garbage at the end of the program, whilst keeping in acceptable bounds for polite conversation. Of course, the INTERCAL doesn't look quite like that in the finished product; I'll explain why as we go.

Buried under a load of Ses

The most obvious issue with the INTERCAL program is that it contains the letter S. This is pretty much unavoidable, as there's no way to index an array without using the letter in question. However, S is an output command in Underload, and there's no way to prevent it parsing the entire program. The only solution is to place the INTERCAL code inside parentheses, Underload's equivalent of a string literal, so that it doesn't run immediately.

However, we have two ^ characters at the end of the program, which execute Underload code; so those Ses are going to get executed anyway if we don't do something about it. I could have changed it to another character, but decided it was easier to protect the code so that it becomes meaningless. a escapes a string in Underload (meaning that ^, upon executing the string, will simply unescape it again rather than producing harmful side effects). We already have one a in the say used in the Perl 6 code (which in this arrangement of the code, is actually enough due to unrelated changes). However, so that people don't have to rely on that, I added another a at the end of the line (I wanted a character there anyway to make what would otherwise be trailing spaces visible, and because Hexagony needed padding as it is; note that the Hexagony was fairly easy to fix in this program, and doesn't really need separate discussion). So the Underload code is a little less fragile than it could have been.

Prelude to a lot of work and confusion

Ah, Prelude. Not normally the most difficult language, but it definitely was this time. There are two real problems: one is that adding extra parentheses on a farly long line runs the risk of disturbing the control flow of the Prelude program (as they create the equivalent of a while loop), and one is simply the problem of preventing them lining up vertically (which is responsible for most of the random moving around of whitespace on lines). Note that the Whitespace gave me some trouble too, but this program is equivalent to the previous one from Whitespace's point of view, so it was pretty much a case of "fix the Prelude without breaking the Whitespace".

I'm not too sure how the Prelude actually works at this point. There are several fixes intended for it, like the 0 near the bottom-left corner, but they clearly don't function in the way I intended them to. (The Julia code also ended up moving to the bottom of the line because the parentheses in its print statement were really hard to deal with.) Perhaps we'll just have to leave it a mystery.

Breakdown in a Fission reactor

Although the changes above were for fairly subtle problems which are hard to fix, there's a much more obvious problem; DOREADOUT matches the regex R...O, and thus will cause Fission to produce unwanted output on the fourth cycle, which is not enough time to output the intended output of 12. And INTERCAL only has one instruction that produces output (unless you count crashing as output). One fix to this is to try to add whitespace between READ and OUT, to give us time to intercept the output, but that makes Whitespace angry. So for a while, I thought this program was impossible; R, L, U, and D are all entry points in Fission, and all capable of potentially running problematic code, and INTERCAL keywords must be in uppercase.

However, there is a fix, and a fairly surprising one. As part of an internationalization effort, C-INTERCAL actually accepts keywords in multiple languages, with support for both English and Latin. We couldn't avoid S like this, but we can avoid O; FAC is a perfectly good substitute for DO, and likewise LEGERE EX means the same thing as READ OUT. (The program thus ended up in a mix of English and Latin, but that's OK; it hardly makes it any less readable.) As such, we can happily let Fission go mad in the bottom right corner, and just not let it produce any output. We can change the actual Fission code to end with * rather than ;, which quits the entire program rather than just one thread; this code runs fairly quickly, so it exits the program before all the stray entry points have time to do any damage.

Knit 6, Perl 6

The next problem: The Perl 6 comments work by matching < and >. INTERCAL's assignment operator is <-. Luckily, that adds extra opening brackets, so I could just add a few closing brackets to cancel them out in an unparsed location in the program (just after the Pip code, in this case).

However, I didn't want to change the whitespace budget of the program, but moving the Julia code (for Prelude) ended up adding an extra space to the last line; I had to remove one from somewhere. The double space is a comment marker in Pip, so I could hardly change those; the only remaining option is the space in say 27. Perl 5 golfers would immediately think "well just do say+27 then" (unary + comes in handy surprisingly often!), but unfortunately this isn't valid Perl 6 syntax.

What we can do, though, is to change say from function syntax to method syntax. Integer literals have a bunch of methods, including one to print them out, so 27.say is a perfectly valid program of the same length.

Be square? Don't be there

So the next issue is that I've added an extra . to the program. SMBF users will know that that's clearly a problem in that language, producing stray output (NUL bytes in this case). There was already a . producing stray output last program, but that doesn't mean I shouldn't take the opportunity to fix it.

The basic idea here is to create an SMBF loop to comment out the offending instructions. This means moving the square brackets around. I took them from around the SNUSP code (because they were only there for the sake of Incident anyway, and Incident doesn't care where in the program they are), and placed the opening bracket at the start of the INTERCAL code, and the closing bracket just before the Trigger (thus neatly hiding both .s).

Unfortunately, square brackets are meaningful to Retina; it sees […<-#… and says "that makes no sense, you can't create that range because < doesn't come before #". Fortunately, this is easily fixable with a strategically placed backslash.

The centre-of-the-program incident

This happened last answer, and it's probably going to happen repeatedly from now on; various strings happened to randomly occur three times, and shifted around the centre of the program from Incident's point of view.

The most urgent token to handle was 1#, which appears three times if you make these changes naively: #= >␉1# at the start of the third line, __DATA__=1#, and echo 21#. Why is this a problem? Because the 1# on the third line overlaps the #v just after it, and two overlapping tokens causes neither of them to be counted. And #v is the token we used to comment the code before the Incident program out! I fixed this by sneaking in an extra 1# very near the end of the program (only three characters follow it); none of the languages that parse that part of the program do anything with it.

There were various other problematic tokens to deal with. A couple were single letters, P and U; I dealt with these via changing a couple of filler no-ops in the Incident code from x to P or U respectively, giving a fourth copy. The change to the Fission code leaves * as a token, but notably, this is split differently from normal, appearing twice before the Incident code and only once afterwards. Instead of removing it, therefore, I used it to partially balance the new LE token that appeared in the INTERCAL code. That's enough to drive the centre of the program back over an 0o token. Of course, changes to the program are quite likely to disturb this. (My attempts to get Incident onto TIO failed due to libdivsufsort not being available there, so it looks like we might benefit from a new interpreter, especially in JavaScript so that it can run online. If you're interested, take a look at this question.)

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Wow, this challenge has come a surprisingly long way. Great job! \$\endgroup\$ Commented Jan 26, 2017 at 17:57
  • \$\begingroup\$ Latin?! Wow, what a great solve! I love that the code says 'please give up' now. It's like it's daring me to quit. \$\endgroup\$
    – Chance
    Commented Jan 27, 2017 at 6:54
21
\$\begingroup\$

31. Modular SNUSP, 326 bytes

Program

#v`16/"<"6/b.q@"(: ::T):  ␉␉␉␉ :(22)S#;n4"14"
#>3N6@15o|>␉^*ttt*~++~~~%
#=~nJ<R"12"; ␉
#[␉
#`<`|
print((eval("1\x2f2")and (9)or(13))-(0and 4)^(1)<<(65)>>62)or'(\{(\{})(\{}[()])}\{})(\{}\{})'#46(8+9+9+9+9+=!)=#print(17)#]#echo 21#|/=1/24=x=9[<$+@+-@@@@=>+<@@@=>+<?#>+.--.]/
#8␛dggi2␛␉` |1|6$//''25  #>say␉␉ 27#T222999+/+23!@"26

As usual, is a literal ESC character and is a literal tab.

Rundown

This program prints 31 in Modular SNUSP, 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng, 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.

Verification

Why no links in the rundown? Because I've been working on something to make testing much easier, a test driver that runs the program in most of the languages listed here and prints the result. This should hopefully make adding future languages to the polyglot much easier. You can get the results of this program for 28 of the 31 languages via running the following TIO link (which is a test driver written in a mix of Bash, Perl, and A Pear Tree):

Try them online!

The link also produces the /-formatted code block seen above, and formats the code into a hexagon for you:

          # v 1 6 / " < " 6 / b
         . q @ " ( : : : T ) : :
        ( 2 2 ) S # ; n 4 " 1 4 "
       # > 3 N 6 @ 1 5 o | > ^ * t
      t t * ~ + + ~ ~ ~ % # = ~ n J
     < R " 1 2 " ; # [ # < | p r i n
    t ( ( e v a l ( " 1 \ x 2 f 2 " )
   a n d ( 9 ) o r ( 1 3 ) ) - ( 0 a n
  d 4 ) ^ ( 1 ) < < ( 6 5 ) > > 6 2 ) o
 r ' ( \ { ( \ { } ) ( \ { } [ ( ) ] ) }
\ { } ) ( \ { } \ { } ) ' # 4 6 ( 8 + 9 +
 9 + 9 + 9 + = ! ) = # p r i n t ( 1 7 )
  # ] # e c h o 2 1 # | / = 1 / 2 4 = x
   = 9 [ < $ + @ + - @ @ @ @ = > + < @
    @ @ = > + < ? # > + . - - . ] / #
     8 . d g g i 2 . | 1 | 6 $ / / '
      ' 2 5 # > s a y 2 7 # T 2 2 2
       9 9 9 + / + 2 3 ! @ " 2 6 .
        . . . . . . . . . . . . .
         . . . . . . . . . . . .
          . . . . . . . . . . .

Three languages are missing: V is too slow, and Reng and Modular SNUSP are not installed on TIO. Luckily, all three have online interpreters:

  • You can test the program in V/Vim (intended output: 2) here on TIO.
  • There's an online Reng interpreter (intended output: 19) here.
  • There's an online Modular SNUSP interpreter (intended output: 31) here. (It's advertised as just a SNUSP interpreter, but Modular SNUSP is the dialect it actually implements, as seen by the @ signs all over the page.)

All three produce the intended output, so all 31 programs are properly tested. (One thing that concerns me slightly is as to whether the Whitespace program is terminating correctly; however, the whitespace here is identical to the previous submission, so they're both right or both wrong. If it turns out that the program is indeed terminating incorrectly, both programs are likely to be fixable in the same way.)

Explanation

First off, the Hexagony, which always seems to need changing. It's actually much simpler than before; I moved the Hexagony code to just after the Trigger code, meaning that it's very near the end of the program, and the Hexagony "capsule" that prints 23 and exits gets to run almost immediately. The last line generally looks like a good place to put the capsule, as it means fewer commands that might potentially disrupt the Hexagony will run.

All the other changes are to do with the addition of the Modular SNUSP code. The first thing to note is that SNUSP starts executing at the first $ character in the program, and is a 2D langauge that exits after going off the edge of the program, and thus by placing the SNUSP program at the end of the long line (inside the Thutu code, at a point where Thutu will accept almost anything), we can ensure that SNUSP doesn't see any code from other languages, and most other languages won't care about the SNUSP. One language that did care was Perl 6, which is parsing angle brackets; I placed a < immediately before the SNUSP code to keep it happy (as the brackets were naturally almost matched anyway). The other language that cares is SMBF; . outputs in both SMBF and SNUSP, and we don't want to create extra output. Luckily, as seen by SMBF, this program is <.>>[…] followed by the SNUSP code, i.e. the current tape element is 0. So enclosing the SNUSP code in square brackets "comments it out" from SMBF's point of view.

As for the code itself, it uses a well-known trick for writing constants in Modular SNUSP in which you write a lot of "start procedure" commands in a row and effectively create a sort of base-Fibonacci number. The basic idea is that + encodes the number 1; @ adds together the number represented by the code after it, and the number represented by the code after it minus its first character; and = is a no-op (thus @= will double the number to its right). In this system, I picked @@@@=+@@@=+# as a representation of the number 48.

There's a problem here, though; the standard method of writing constants in SNUSP leaves the control flow behind the start of the program, and with a oneliner (which I wanted to write here for obvious reasons), there's no way to change the IP to point in any direction but right. This means we're somehow going to have to get the IP to pass the entire constant definition and continue to the right, without the program exiting (which # would normally do). In order to resolve this, I carefully used a definition of the number for which + was always preceded by =. This means that I can write code to set the second cell to 48 via @@@@=>+<@@@=>+<#, safe in the knowledge that none of the > commands will be skipped by an @ command (and thus we keep control of the tape pointer). Additionally, we know that at the final #, the first tape cell will still have its initial value. Therefore, we can use the first tape cell as a marker to know whether to return from the procedure definition or whether to continue to the right (we're inside a ton of procedures when doing that, but we exit the program by falling off the edge so that it doesn't matter).

The final SNUSP code, therefore, is $+@+-@@@@=>+<@@@=>+<?#>+.--.. The $ marks the start of the program. +@+- sets the first tape element to 1 (++-, but once the procedure started with @ returns, it'll start running the code from the - onwards, thus setting the tape element back to 0. ?# ends the procedure only if the first tape element is nonzero; thus we eventually end up after the # with the second tape element set to 50 (48 from the constant definition, plus 2 from the two >+< encountered when going to the right afterwards). Then all we need to do is >+.--. to output ASCII codes 51 (3) and 49 (1), and fall off the edge of the program (] is a no-op in SNUSP, and / reflects control flow vertically so that it runs off the program's top edge); this bit works identically to brainfuck.

\$\endgroup\$
21
\$\begingroup\$

51. Assembly (x64, Linux, AS), 1086 bytes

#16  "(}23!@)(" 3//*v\D@;'[af2.qc]'#)"14";n4
#/*` PkPPZ (22)S"[!(>7 7*,;68*,@;'1,@␉␉␉␉ q
#>␉
# >36!@␉
#`<`
#<]+<[.>-]>[
#{
#z}
#
#=x<R+++++[D>+++++++EAL+++<-][pPLEASE,2<-#2DO,2SUB#1<-#52PLEASE,2SUB#2<-#32DOREADOUT,2DOGIVEUPDOiiipsddsdoh]>+.-- -. >][
#x%+>+=+~tt .
#D>xU/-<+++L
#R+.----\).>]|
#[#[(}2}20l0v01k1kx0l0ix0jor0h0h1d111x0eU0bx0b0o1d0b0e0e0@O6O4/0m1d0i0fx0g0n0n11x0o0n0cx0c0o0f0c0gx0g0f0h0j0j0i0001k10vx0v0l111111^_)  0046(8+9+9+9+9+=!)
###|
'\';echo 50;exit;';print((eval("1\x2f2")and(9)or(13))-(0and 4)^1<<(65)>>(62))or"'x"or'({({1})({1}[(0)])}{1}\{1})'#}#(prin 45)(bye)|/=1/24=x<$+@+-@@@@=>+<@@@=>+<?#d>+.--./
__DATA__=1#"'x"//
#.\."12"__*'
###;console.log 39
""""#//
=begin //
#sseemeePaeueewuuweeeeeeeeeeCisajjap*///;.int 2298589328,898451655,12,178790,1018168591,84934449,12597/*
#define p sizeof'p'-1?"38":"37"
#include<stdio.h>
main ( )/*/
#
#"`#"\'*/{puts (p);}/*'"`"
/*
<>{#65}//
#}
disp 49#//
#{
1}<>//
$'main'//
#-3o4o#$$$
#<R>"3"O.
=end #//
"""#"#//
#}
#s|o51~nJ;#:p'34'\=#print (17)#>27.say#]#print(47)#]#echo  21
#sss8␛dggi2␛ `|1|6$//''25  16*///89^_^_Z222999"26

is a literal tab, a literal ESC character; Stack Exchange would mangle the program otherwise. I recommend copying the program from the "input" box of the TIO link below, if you want to work on it.

Want to learn more? Try the polygot chat!

Try it online!

VIP score (Versatile Integer Printer): .008186 (to improve, next entry should be no more than 1151 bytes)

This program prints 51 in Assembly, 50 in Bash, 49 in Octave, 48 in Deadfish~, 47 in Lily, 46 in Cubix, 45 in PicoLisp, 44 in alphuck, 43 in reticular, 42 in evil, 41 in brainf***, 40 in Minimal-2D, 39 in CoffeeScript, 38 in C, 37 in C++, 36 in Labyrinth, 35 in INTERCAL, 34 in Rail, 33 in Incident, 32 in Whirl, 31 in Modular SNUSP, 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng, 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.

Verification

Most of the languages are tested by the test driver shown above.

  • Reng can be tested to output 19 here.

  • Modular SNUSP can be tested to output 31 here.

  • Cubix’s cube shape viewed here

  • Incident is checked by keeping the tokens balanced as described in previous answers.

  • For Deadfish~, can be tested to output 48 with this. Note that Deadfish~ takes the polyglot to be fed on stdin, but and prints a number of >> prompts to standard output, which are an unavoidable consequence of running any Deadfish~ program.

  • Assembly can be tested to output 51 here

Thanks and Congratulations

When @ais523’s 50-in-1-k answer dropped 2 weeks ago, a tear rolled down my cheek. It was too beautiful. And it was in Bash. It was too perfect.

I turned to my wife and said “I think the polyglot is done,” feeling immense pride.

She turned to look me in the eye, paused a moment, and said “Good. Now take out the trash.”

What she meant though was that she felt deep joy for me and my internet friends. Thanks and congratulations to everyone.

Assembly Explanation

In the days that followed, my mind kept wandering back to something @ais523 said in polyglot chat shortly before posting Bash. He pointed out that some flavors of assembly use # based line comments and /* block comments. Well that was enough for me to slowly lose my mind for the next 2 weeks.

There is a kind of implicit challenge in polyglots to include legitimate languages. I’m using the term legitimate here very loosely, but I think we can all grok what I’m getting at. It’s a one thing to include Brainf***, but it’s another thing entirely to include the likes of Mathlab or R. Assembly certainly falls into the latter category, and my mind couldn’t let it go. But I knew nothing of Assembly, so this was an uphill battle.

After banging my head against the problem for a while, looking for a way for Assembly and C/C++ to coexist, I found this is the documentation for the GNU assembler:

To be compatible with past assemblers, lines that begin with '#' have a special interpretation. Following the '#' should be an absolute expression (see Expressions): the logical line number of the next line. Then a string (see Strings) is allowed: if present it is a new logical file name. The rest of the line, if any, should be whitespace.

This I noticed happened to be quite similar to our pre-processor directive for C/C++ in line 1 of the polyglot. After some trial and error I found that #1 “bla” 1//* would enter a block comment for Assembly only.

And so a polyglot was made.

With the biggest blocking problems solved, I set out to golf down this hello world example.

.intel_syntax noprefix
.section .data
     msg: .asciz "51"
.section .text
.global _start
_start:
    # write syscall
    mov     rax, 1
    # file descriptor, standard output
    mov     rdi, 1
    # message address
    mov     rsi, OFFSET FLAT:msg
    # length of message
    mov     rdx, 14
    # call write syscall
    syscall
    #End the Program
    mov    rax, 60
    mov    rdi, 0
    syscall

Primary Author’s Credit

Actually I lied a minute ago, the very first version of the Assembly code I used was in AT&T syntax, which is one of two syntactic branches of Assembly. One of the main elements of AT&T syntax is that it’s register references use a % prefix and this is a problem for the polyglot. Cardinal uses % as a pointer origin, so if we littered a bunch of % about, it’d be like a second Fission reaction.

The other syntactic branch, which doesn’t use % as a register prefix, is called Intel syntax. The exploit we’re using in the polyglot to get past the first line and enter a block comment is in the GNU Assembler (GAS or AS for short). AS has the happy feature of allowing both syntactic branches. You just have to declare that you want to use Intel syntax, which is happening on Line 1 of the Assembly code.

Assembly uses registers, which are a small number of memory locations literally located on the CPU for speed of access. This isn’t unique to Assembly other than the fact that their use is not abstracted away from the developer’s concern.

There are different kinds of registers which are used for different purposes. From Wikipedia:

• AX multiply/divide, string load & store

• CX count for string operations & shifts

• DX port address for IN and OUT

• BX index register for MOVE

• SP points to top of stack

• BP points to base of stack frame

• SI points to a source in stream operations

• DI points to a destination in stream operations

AX is used in line of the _start Function here: mov rax, 1. The r in rax indicates that the memory is 64-bit. If we swapped this for an e, that would indicate a 32-bit memory, which is totally valid to do with a 64-bit processor. We just wouldn’t use the top half of the available memory. To indicate 16-bit memory, you just use ax, which is fine for us because we’re just printing integers. So we can golf a few bytes by changing all the register references to 16-bit.

Okay, not quite all the register references could drop the r. mov rsi, OFFSET FLAT:msg. If you’re familiar with Assembly, but not this statement, it’s because this was semi unique to AS. At least, that what I gleaned from this, which helped me gold down the statement to just lea rsi,m.

After this, I experientially found that I could knock _start: down to just _p and cut .global _start entirely with only a warning issued. Second, msg: was reduced to just a single character variable p:. I chose p for both the string variable and the starting function to offset some of the s Assembly added for Alphuck’s benefit.

Then, I put in ; to delimit instructions in order to put them all on one line. This is primarily to avoid excessive trailing #//s on each line for Thutu’s benefit. Also, I noticed that our Assembler didn’t appear case sensitive, so I just upper or lower cased various characters to avoid Incident imbalance.

This golf'd us down to:

.intel_syntax noprefix;.text;mov ax,1;mov di,1;lea rsi,m;mov dx,2;syscall;mov ax,60;mov di,0;syscall;m:.asciz "51"

After all this, Japt and Underload were the only problem children in this answer. Japt had some beef with the * added in line 1, but it seemed to be fixed by reverting to the puts(p); line from the C++ answer. I ended up throwing a ( in this line as well and then closing it on Octive’s line. This was so Underload would stop sefaulting. A similar treatment was had on line 1 to add in the * there.

This was enough to meet the byte requirements of this challenge. In fact I verified this by producing this version of the polyglot. But I wanted to attempt to improve the VIP score as well if possible. And since I had a fulfilled all the requirements of the challenge, I felt ok about collaborating to golf down the code. So I stopped over at polyglot chat to seek some golfing help.

We must go deeper

@ais523 demonstrated a technique of passing the instructions to the assembler as machine code with this statement.

.text;.long 2298589328,898451655,12,178790,1018168591,84934449,12597 Machine code is a series of numeric instructions executed directly by the CPU which can be represented in decimal, Hexadecimal or Octal. For our purposes decimal is the shortest since (hex takes a leading 0x to represent). The .long statement here is making the declaration that what follows is a series of decimal machine code instructions.

Well I poked at this statement as well for a bit to see what the assembler would allow, and made a couple changes. First, I found that I can remove .text; all together, with only warnings issues, which was a pretty sold byte saving. Then a while later I also found, this statement in the AS spec documentation

.long is the same as .int

Cool. So, we can make that swap for a quick byte. Now our assembly, but really machine code, was cut down to this:

.int 2298589328,898451655,12,178790,1018168591,84934449,12597.

While this is all well and good, it’s quite difficult to work with machine code directly and I wanted to at least see how to make all the translations. So ideally, we’d want to dissemble the machine code back to assembly. The easiest way of doing that is to take an object dump, which @ais523 demonstrated for me with this code snippet.

Here’s the code snippet.

And here’s just the Assembly.

nop
mov    $0x1,%al
mov    %eax,%edi
lea    0xc(%rip),%rsi
mov    $0x2,%dx
syscall 
mov    $0x3c,%al
xor    %edi,%edi
syscall 
.byte 0x35
xor    %eax,(%rax)

That link also shows some 2 character hex numbers alongside each line of assembly. Those correspond to the decimal instructions. For example, if you put 2298589328 into this decimal to hex converter, you get 8901B090 back. And if you look closely, those are the first 4 hex instructions from the object dump (in reverse order).

From what I can tell, sets of 4 hexadecimal numbers are always used to convert to decimal and the main byte saving trick being use here is to structure the assembly so that the last several hex numbers in our 4 sets are 00. These will then transform to leading zeros when we put them into the .int statement which are just omitted.

This is what’s happening in the 12 statement. In hex portion of the object dump this is 0c 00 00 00.

This is as far as my understanding of Assembly has gotten in 2 weeks. What a crash course!

Incident

Incident was a more difficult solve in the shorter assembly implementation because it weighted the polyglot tokens much heavier to the top. Here is the Incident report.

  • ! in line 2 detokenizes !

  • The first EA on the INTERCAL line detokenizes itself

  • The last space on the second to last line detokenizes a space-space token.

  • 85 on the last line detokenizes

  • The R in #<R>"3"O. detokenizes R

  • 65 in <>{#65 }// tokenizes 65

  • 16 on the last line detokenizes itself

  • 89 on the last line tokenizes itself

Cardinal

I just realized I made a change to Cardinal that I forgot to document. I spent some time poking around looking for ways to save bytes, and decided to learn Cardinal. After a little time with the documentation, I saw this line.

= copies the pointer's active value into its inactive value.

This was not a trick being used in the polyglot. The old solution included these instrucitons: `++~*t

++ incriments up to 2.

~ changes the active stack

* adds the stacks.

I realized that ~* could be achieved with just the = instruction, so I reworked the solution to take out some useless stack swapping and add in this small byte saving.

\$\endgroup\$
4
  • 3
    \$\begingroup\$ I'm intrigued as to how you can even keep polyglotting to this amazing stage. How??? \$\endgroup\$
    – clismique
    Commented Apr 5, 2017 at 7:19
  • 3
    \$\begingroup\$ This is truly a thing of pure beauty. \$\endgroup\$
    – Muzer
    Commented Apr 5, 2017 at 15:37
  • \$\begingroup\$ Unary should be next \$\endgroup\$
    – user63187
    Commented Apr 6, 2017 at 16:00
  • \$\begingroup\$ No, that would murder the VIP score (unless the code was 3 bytes or less) \$\endgroup\$ Commented Apr 26, 2017 at 16:24
19
\$\begingroup\$

1. Python 3 (8 bytes)

print(1)

This program prints 1 in Python 3.

Starting this off with Python 3 because I know it's good for polyglots and can be taken in a number of different directions (also, I wanted to ensure that the first answer was in a relatively normal language, rather than an absurd esolang that's hard to polyglot with).

\$\endgroup\$
3
  • \$\begingroup\$ Would ><> be a good choice for the 2nd language (so that we start 2d space)? \$\endgroup\$
    – user41805
    Commented Dec 6, 2016 at 19:07
  • \$\begingroup\$ So that means the next answer can't be more than 9 bytes? That's gonna be really hard to come up with another one. \$\endgroup\$
    – DJMcMayhem
    Commented Dec 6, 2016 at 19:09
  • 2
    \$\begingroup\$ @DJMcMayhem Each answer must be no more than 20% or 20 bytes (whichever is larger) longer \$\endgroup\$
    – user41805
    Commented Dec 6, 2016 at 19:10
19
\$\begingroup\$

10. Befunge, 95 bytes

#v02^0;7||"<+0+0+0+<;n4
#v0#@00
#>3N.
#|\w*
#8
#|
#M`
print(None and 9or 1/2and 1or 5)
#jd5ki2

There is a literal ESC character between j and d on the last line (grr, @ais523). It is not included in this code. To get the actual code, please go to the Try it online link.

This prints 1 in Python 3, 2 in Vim, 3 in Minkolang, 4 in <><, 5 in Python 2, 6 in SMBF, 7 in Japt, 8 in Retina, 9 in Perl, and 10 in Befunge.

This code shares * with Retina and . with Minkolang and SMBF.

Try it online

Explanation

Actual program

#v02^
    @
    .
    *
    
    
   
    t
    5
#v02^

The last line was written for clarity (Befunge playground is cyclic.)

#

Trampoline, skips v

02^

Push 0 and then 2 in stack and go up.

5t*.@

Push 5, no-op, multiply two elements in stack (2 and 5), print, end program.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ This makes SMBF print a null byte at the first .. \$\endgroup\$ Commented Dec 7, 2016 at 0:31
  • \$\begingroup\$ @Pietu1998 fixed! \$\endgroup\$ Commented Dec 7, 2016 at 1:31
  • \$\begingroup\$ Hey, it wasn't me who chose to use a language where many of the most important commands are nonprintable characters… (In other news, I was considering Befunge as a strong possibility for adding to this polyglot; it seems to fit in well with the other languages. I like the way you did it, although it may well need modifying to fit in more.) \$\endgroup\$
    – user62131
    Commented Dec 7, 2016 at 2:26
  • \$\begingroup\$ @ais523 I agree that modifying this code may be difficult. To alleviate this, I put in some 0s to indicate that those characters can be anything (except the "<+0+0+0+<;n4 part) and parts of the Befunge code may be moved around. And a tip for the next person: most of characters are no-op in Befunge, so adding more lines is not likely going to affect the Befunge code. \$\endgroup\$ Commented Dec 7, 2016 at 2:36
  • \$\begingroup\$ Thinking about making a befunge-98 (or other similar funge) submission, because they add a fair amount of operations that are no-ops in regular '93. It might be hard to fit though, and I would need to figure out how all the other languages worked so I could work around them... \$\endgroup\$ Commented Dec 7, 2016 at 5:30
19
\$\begingroup\$

11. Befunge 98, 102 bytes

#v;2^0;7||"<+0+0+0+<;n4
#v0#_q@
#>3N.
#|\w*
#8  ^1b0<
#|
#M`
print(None and 9or 1/2and 1or 5)
#jd5ki2

Prints:

To be perfectly honest, I have no clue why the Vim code takes 1 min to output. Also, no clue how Retina works.

Explanation:

#v          Skips the v, which would send the IP down
  ;         Unlike '93, where ; is a no-op, '98 skips to the next ;
            and doesn't execute anything in between
   2^0;     Not executed, unlike Befunge 93
       7|   Pushes 7 onto the stack, and then sends the IP up, because 7 is not 0
n0b1        n clears the stack, and #s are pushed until the stack is [0, 11, 1
    *.      multiplies the top 2 values of the stack to give 11, and prints it (yay!)
      _     Sends the IP right, because the top value of the stack is 0
       q    Ends the program (no-op for '93, which continues to @)

Things to note:

  • The 0 next to the b isn't strictly necessary in the code's current state, and the stack has been cleared. It can be removed if necessary, but allows for other stack manipulation beforehand as part of a possible future program.
  • The _q@ is there as part of Retina (It doesn't work without it, don't ask me why). The addition of q also lets the '98 code run a t operation, which splits the IP (along with making the Retina program print 8 instead of 7)
  • The _ is not a simple > because that would mess the SMBF part up.

Edit: Just realized that the _q@ should probably be @00 (Where 0s can be ~any char) to make the program more flexible in the future. I'm too lazy (and tired) to change all the links right now though. Will get around to it eventually...

Edit 2: I Didn't expect 6 more answers this quickly. I guess it's staying as is. Great job everyone!

\$\endgroup\$
4
  • \$\begingroup\$ Heh, I wrote my 11th answer, only to realise that it had already been posted, now I changed it to the 12th answer :) \$\endgroup\$
    – user41805
    Commented Dec 7, 2016 at 8:26
  • \$\begingroup\$ Any Idea why Vim takes so long to execute? \$\endgroup\$ Commented Dec 7, 2016 at 16:15
  • \$\begingroup\$ @MistahFiggins I guess it is because the code has to be converted to keystrokes, but other than that, I have no clue \$\endgroup\$
    – user41805
    Commented Dec 7, 2016 at 16:16
  • \$\begingroup\$ I wrote that vim interpreter, and I have no idea why it takes so long. I haven't noticed many performance issues before, but that's because most of my V/Vim answers are less than 40 bytes. Not really sure what's causing it, but lots of people have been complaining about that on this thread. \$\endgroup\$
    – DJMcMayhem
    Commented Dec 7, 2016 at 23:00
19
\$\begingroup\$

21. Nim (161 bytes)

#v`16/"<"6/b.q@#;n4"14""
#>3N6@15o|> ^*ttt*~++ %
#=~nJ<R"12";
#[

print((1/2and 9 or 13)-(0and+4)^1<<65>>62)#46(89999+++++!)=#print(17)#]#echo 21
#8dggi2` |1|6

Two <ESC>s, between 8d and between 2` on the last line. You can tell that my previous one was golfed in a hurry, because I woke up this morning and realised I could take a bunch more off. I had 152 bytes but that seems to only work in Perl 5.24.0, so in the interest of compatibility with TIO I've kept the original expression for now.

Prints 1 in Python 3, 2 in V, 3 in Minkolang, 4 in ><>, 5 in Python 2, 6 in SMBF, 7 in Japt, 8 in Retina, 9 in Perl, 10 in Befunge-93, 11 in Befunge-98, 12 in Fission, 13 in Ruby, 14 in Turtléd, 15 in Haystack, 16 in Pyth, 17 in Julia, 18 in Cardinal, 19 in Reng, 20 in Prelude and 21 in Nim.

Note that Nim on ideone.com uses version 0.11.2, which is a tad too old, since this program relies on #[ ... ]# multiline comments added in early 2016.

Thanks to Cardinal's Windows interpreter, my workflow now consists of two laptops and a Python http.server in between.


Edit — some more hints:

  • The 8 at the start of the last line is to set Retina's limit to the first 8 matches, otherwise without it Retina would output 2. Note that this means the final line regex only needs to match at least 8 times in the second last line now, as opposed to exactly 8 — during my meddling I modified Prelude to get Retina right, but it turned out that was unnecessary in the end.
  • The mismatched quote at the end of the first line is so that Pyth doesn't complain about invalid syntax for the rest of the code.
  • If you modify the second line you might have to change the 6@ for Minkolang, which makes the pointer jump 6 spaces to land on the ^.
  • There's a pair of [] now, so SMBF needs to be on a 0 cell before it hits the [, or alternative the interior needs to clear the cell.

There's probably more to golf (even now I see a stray space before the % for Cardinal), but I should really stop golfing in the wee hours of the morning.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ TIO now supports Cardinal \$\endgroup\$ Commented Dec 8, 2016 at 19:17
18
\$\begingroup\$

36. Labyrinth, 647 bytes

#v`16/"<"6/b.q@"(: ::Q):  ␉␉␉␉ :(22)S#;n4"14"
#>3N36!@@15o|>␉^?.*ttt*~++~~~%
#= >␉1#v#v0l0mx01k1k0l0ix0jx0h0h1d111P0eU0bx0b0o1d0b0e0e00x1d0i0fx0g0n0n11x0o0n0cx0c0o0f0c0gx0g0f0h0j0j0i0001k10mx0m0l11111100(^_)
#[␉
#`<`|
print((eval(" 1\x2f2")and(9)or(13))-(0and 4)^1<<(65)>>(62))or' (\{(\{})(\{}[()])}\{}\{}\{})'#46(8+9+9+9+9+=!)#1111|=/=1/24=x=9[<$+@+-@@@@=>+<@@@=>+<?#>+.--.]/
__DATA__=1#//
#.\."12"␉*
""""#//
=begin␉//
$'main'//
#-3o4o#␉
=end   #//
"""#"#//
#0]#echo 21#/ (\[FAC,1<-#2FAC,1SUB#1<-#52FAC,1SUB#2<-#32FACLEGEREEX,1PLEASEGIVEUPPLEASE) a
#   +/Jn~
#0␛dggi2␛`␉|1|6$//''25  >>>#>27.say# =#print(17)#$nd^_^_.]Q2229991#;abcd!fghij/+23!@"26

is a literal tab, a literal ESC character; Stack Exchange would mangle the program otherwise. I recommend copying the program from the "input" box of the TIO link below, if you want to work on it.

Try them online!

Rundown

This program prints 36 in Labyrinth, 35 in INTERCAL, 34 in Rail, 33 in Incident, 32 in Whirl, 31 in Modular SNUSP, 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng, 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.

Verification

Most of the languages are tested by the test driver shown above. You can test Reng here and Modular SNUSP here; they output 19 and 31 respectively. @ais523 helped debug and fix the Incident code, which now works.

How Labyrinth works

Labyrinth starts off shifting some of the columns in the source around a little, but after a few steps the pointer gets to where the N is on the 2nd line (initially, by the time the pointer gets there it's no longer an N there), moving right, with a 0 at the top of the stack. Then, it simply pushes and prints a 36 and terminates with 36!@

Things I Done Broke

I knew I wanted to add Labyrinth, as it's one of the few esolangs I know a bit about. With it's debugger, I found that by changing the 8 in the last line to a 0, Labyrinth didn't get stuck in an infinite loop and, oddly, nothing else seemed to break. From there I just dumped in the raw 36 and output command I needed, and those conveniently led to an @ to terminate things.

Then, it was on to repairing what I broke: Minkolang, Cardinal, and Hexagony.

The ! was making Minko skip the next character, which it needed to terminate, so I just added an extra @. So far, so good.

The change in length of the 2nd line made Cardinal miss it's output statement. Trying to add an extra . on the first line made Prelude lose its mind (no clue why, honestly), so I went a different method and just dropped it in the second line. That inadvertently spawned a 3rd Cardinal pointer, so I padded things with a ? (not a necessary choice, just the first thing I found that fixed both Fission and Cardinal).

Hexagony was fortunately a relatively simple fix, I just threw in a string of letters so that the pointer found the code. I figured the alphabet shouldn't have appeared before and wouldn't cause problems with Incident. This is also when I realized I hadn't tested Incident. Thanks to @ai523, I found out I just needed an extra exclamation point, so the e in the alphabet string was changed to a !.

Scores from The versatile integer printer

Just for kicks and going of off @Stewie Griffin's comment on the question, here's a snippet that shows how each answer would have scored if it was entered into "The Verstatile Integer Printer".

// This was stolen/sloppily hacked together from the snippet here: https://codegolf.stackexchange.com/questions/55422/hello-world. Feel free to clean it up if you'd like.
/* Configuration */

var QUESTION_ID = 102370; // Obtain this from the url
// It will be like http://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 8478; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "http://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=asc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "http://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });  
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*)[,\(].*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function getScore(langs, bytes) {
  var l = Math.pow(langs,3);
  return bytes/l;
}

function process() {
  var valid = [];
 
  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
    });
    
    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
        score: getScore(match[1].split(".")[0],+match[2]).toFixed(5),
      });
    else console.log(body);
  });
  
  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;
    
    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    lang = jQuery('<a>'+lang+'</a>').text();
    
    languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link, score: a.score};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    return a.lang_raw.split(".")[0] - b.lang_raw.split(".")[0];
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.score)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body { text-align: left !important}

#language-list {
  padding: 10px;
  width: 400px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="language-list">
  <h2>Scores from <a href="https://codegolf.stackexchange.com/questions/65641/the-versatile-integer-printer">The Versatile Integer Printer</a></h2>
  <table class="language-list">
    <thead>
      <tr><td>Language</td><td>User</td><td>Score</td></tr>
    </thead>
    <tbody id="languages">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

\$\endgroup\$
2
  • 1
    \$\begingroup\$ OK, it looks like this only slightly causes problems with Incident; the program's off-centre due to now having exactly three exclamation marks, but this can easily be fixed by changing a filler character to a fourth exclamation mark. I changed the e in the alphabet you added to an exclamation mark; that seems to work. \$\endgroup\$
    – user62131
    Commented Jan 27, 2017 at 22:05
  • 1
    \$\begingroup\$ Nice! I've been secretly waiting for labyrinth, so good on you. On a separate note, the best part of the code so far (for me) is the "PLEASEGIVEUPPLEASE" message, telling you to just stop trying. ;) \$\endgroup\$ Commented Jan 30, 2017 at 5:45
18
+100
\$\begingroup\$

41. brainf***, 916 bytes

#  4"16" 3//v\(@#/;\D"14"<;n4
#/*`3 afaaZ">;[77*,68*,@;'1,'1,q)(22)S#   ␉␉␉␉ (
#yy␉;36!@
#`<` ␉
#=␉x
#<]+<[.>-]>[
#␉<
###xR+++++[D>+++++++L+++<-][<<<]>+.---.>][
#px%>~~~+␉+~*ttt*.x
#D>xU/-<+++L)
#R+.----.R␉>]|
#[#yy#yy0l0mx01k1k0l0ix0jx0h0h1d111P0eU0bx0b0o1d0b0e0e00x1d0i0fx0g0n0n11x0o0n0cx0c0o0f0c0gx0g0f0h0j0j0i0001k10mx0m0l11111100(^_)
#|␉
print((eval("1\x2f2")and(9)or(13   ) )-(0and 4)^1<<(65)>>(62))or'(\{(\{})(\{}[()])}\{}\{}\{})'#46(8+9+9+9+9+=!)#1111|=/=1/24=x=9[<$+@+-@@@@=>+<@@@=>+<?#>+.--.]/
__DATA__=1#//
#.\."12"␉*
###; console.log  39
""""#//
=begin␉//
#*/
#define␉z  sizeof 'c'-1?"38":"37"
#include<stdio.h>
int main()  /*/
#()`#`\'*/{puts(z);}/*'``
$'main'␉//
#-3o4o#$$$
<>"3"O.<␉>//
#
=end   #//
"""#"#//
#0]#echo 21#/(\[FAC,1<-#2FAC,1SUB#1<-#52FAC,1SUB#2<-#32FACLEGEREEX,1PLEASEGIVEUPPLEASE)  a>>>
#>27.say# /7Jn~15o|  
#8␛dggi2␛`␉|1|6$//''25  =#print(17) ###^_^_LEintnd"3"z!]/}23!@/*///Z222999"26

is a literal tab, a literal ESC character; Stack Exchange would mangle the program otherwise. I recommend copying the program from the "input" box of the TIO link below, if you want to work on it.

Try it online!

VIP Score (Versatile Integer Printer): 0.01329

Rundown

This program prints 41 in brainf***, 40 in Minimal-2D, 39 in CoffeeScript, 38 in C, 37 in C++, 36 in Labyrinth, 35 in INTERCAL, 34 in Rail, 33 in Incident, 32 in Whirl, 31 in Modular SNUSP, 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng, 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.

Verification

Most of the languages are tested by the test driver shown above. You can test Reng here and Modular SNUSP here; they output 19 and 31 respectively, as required.

The Test Driver has been updated to include the Tokenizer, finally. All the C code is stored as an argument from the Bash Script’s perspective. I also changed the output to wrap horizontally with a trailing space after each token instead of outputting vertically. This was just my preference, to make it match the Whitespace output. But anyone else can change it if they feel like it’s too confusing.

I also made a Test Driver adjustment to handle column spacing for Turtlèd’s UFT8 char in the rundown. That misalignment was driving me nuts! The “fix” is pretty hack-ish since it just looks for an è and changes the column width for that case, but it gets the job done.

Explanation

First off, I want to say how awesome @SnoringFrog’s Versatile Integer Printer Score Rundown code snippet from the last post was. I’ve been calculating answers before posting for a while, and this has re-inspired me keep it small. I think we can beat @sp3000’s answer eventually.

So I started working on this answer by trying to golf down what I could and I was pretty successful. I even had an answer in a different language with a total byte count smaller than #40. But as I tried to golf down Minimal-2D, I had to learn BF so I could better work with its derivatives and in the process I found @Primo’s record breaking Hello, World!. I fell in love the elegance.

Minimal-2D, it turned out, was not efficient enough to utilize the tape initializing technique used by @Primo, but I’m of the opinion now that it would probably be too byte heavy anyways. We are only trying to print an integer after all. But @Primo did send me down the path to learning how to multiply in BF, which I brought to the Minimal-2D’s code.

Then after all this, I re-read @SnoringFrog’s comment about how to include BF and realized that not only could I do it, but I could use much of the Minimal-2D code I had golfed down in the BF answer. So I dug in to answer with BF, and here we are.

One more thing before I get into the details. There were a couple changes I made for non-golf reasons. First, I moved the bulk of the code @SnoringFrog added to just below the 2D languages in the top several rows. To me, it is a long term strategic move to prevent 2D-langs from traversing the center of the polyglot in order to prevent future bugs where possible. The byte hit was low for this move, so I went for it.

Second, during the various re-factors I learned that the Begunges and Minkolang output a trailing space after numeric outputs and that this was the cause of the null bytes we’ve been seeing in the Test Driver for these languages. I fixed these by outputting the stack’s value as an ascii code (which did not include the trailing space feature), instead of the value directly. There was a small byte hit for this change as well, but now the Test Driver’s output is so uniform. How could I not?

SM/BF

Let’s quickly go over the basics. These are the only valid commands for SMBF and BF:

>   Move the pointer to the right
<   Move the pointer to the left
+   Increment the memory cell under the pointer
-   Decrement the memory cell under the pointer
.   Output the character signified by the cell at the pointer
,   Input a character and store it in the cell at the pointer
[   Jump past the matching ] if the cell under the pointer is 0
]   Jump back to the matching [ if the cell under the pointer is nonzero

Both languages have a memory tape where values are stored and changed. SMBF’s only difference is that whatever code is being executed is also stored on the memory tape to the left of the starting point. As @SnoringFrog pointed out, getting SMBF and BF to produce different results hinges on moving the memory pointer to the left of the origin. In Tio’s BF interpreter, the memory pointer is capable of moving left of the origin and will find 0’s instead of the Polyglot’s ascii codes that SMBF sees. Here’s an example that can be run in both SMBF and BF to exemplify the difference.

At the start of the polyglot, the Befunges require the > on the second row to run to completion and Perl6 requires that every > be preceded by a <. So SM/BF start with <> to leave the memory pointer at the origin, then hit a [ which jumps some offensive characters for both languages to the ] on the 6th row.

Next, we increment the origin memory cell for both languages and move the memory pointer to the left with +<. (For conversational convention, we’ll call the origin memory cell as cell 0, cells to the right of the origin 1, 2, ... And cells to the left -1,-2, …). Cell -1 contains the asci code of the last character in the polyglot in SMBF and 0 in BF, so when the next [ is encountered, only BF jumps to the next ] while SMBF passes into the code.

As SMBF traverses [.>-] it prints the 6 found at the end of the polyglot and then moves the memory pointer back to cell 0, setting its value back to zero to exit the ]. To review, the tapes at this pint are: SMBF’s negative cells hold the polyglot, and it’s 0 and positive cells hold zero. BF’s negative and positive cells hold zero while it’s origin cell holds 1.

Next the > moves SMBF to cell 1 and BF back to cell 0 allowing BF to enter it’s private code block: [<+++++[>++++++++++<-][<<<]>+.---.>] (I’ve removed the non-BF characters from this). Here, we move back to cell -1 and initialize our loop control variable (cell -1) to a value of 5. Then we enter the loop where we add 10 to cell 0 and decrement cell -1 five times before exiting the loop where we will be pointing at cell -1 with a value of 0.

Next we encounter [<<<] while pointing at a zero, so BF doesn’t pass through this. The purpose here is to balance a number of >’s with preceding <’s so Perl6 doesn’t error out.

At this point cell 0 is valued at 51. The ascii value of 4 is 52, so we move the pointer to cell 0 add 1, then print the value. And finally, we decrement cell 0 back to the ascii character 1 and print again before setting the memory pointer to cell 1 (value 0) to exit past the ].

SMBF and BF both hit the last [ on line 8 next while both are resting on a 0 value. So both jump past the remaining Minimal-2D code until the ] is encountered on line 11. But this is short lived because line 12 starts with another [ which takes both languages to almost the end of the polyglot where no further instructions are encountered.

Refactors

Minimal-2D

Minimal-2D’s re-write was mostly to save some bytes in a fashion similar to BF’s multiplication trick. Minimal-2D however doesn’t have the [ and ] characters for loop control. Instead it has these commands:

/   Skips next instruction if the data pointer is set to 0.
U   Tells the program to switch to the up direction of processing instructions.
D   Tells the program to switch to the down direction of processing instructions.
L   Tells the program to switch to the left direction of processing instructions.
R   Tells the program to switch to the right direction of processing instructions.

These can be used to produce the same logic structure, albeit in a 2D manor, as that of BF. For example, BF’s ++++++[>++++++<-]>. is equivalent to this in Minimal-2D.

Here is a simplified version of Minimal-2D’s code in the polyglot, with all the extraneous code removed and all the place holding characters replaced with #.

###################D
###R+++++[D>+++++++L
###>
D>#U/-<+++L)
R+.----.R

The D in line 1 sends the instruction pointer down to the L in line 8 of the polyglot which sends the pointer to the left. Here we set the loop control variable (cell 0) to 7, move the memory pointer to cell 1 and enter a loop. In loop, we add 3 to cell 1, decrement cell 0 then check if cell 0’s value is zero yet. If not, we add another 8 to cell 1 then decrement and check again. The result of this loop is cell 1’s value is set to 51 at the end of the loop (6*8+3).

We exit the loop by hopping the U, moving the memory pointer to cell 1 and going down then to the right on line 11 of the polyglot. And finally, we increment up to the ascii value for 4 then decrement down to the ascii value for 0 before running off to the right to end the program.

Retina

Retina had a lot of requirements that were difficult to work with for all the BF derivatives. It doesn’t like consecutive +’s or mismatched () or []. But these are really just requirements for every other line, so a lot of the work for BF, SMBF and Minimal-2D revolved around putting the bulk of the code on even numbered lines.

The one byte committed solely to Retina though is the | at the end of line 11. To quote @ais523 “most regexes ending with | will match anything”. Without this, Retina returns 0. Why this fixes it, I don’t know. I haven’t had to dig into Retina too much, probably because I’ve been avoiding the long line. But like Prelude, I’ve found I don’t need to understand it as much as I need to understand how to debug it, which in this case mostly consisted of deleting lines (in multiples of 2) until I’ve found the line that’s causing it to break. I guessed at this fix based on @ais523’s comment, and was rewarded. I’m just too cool for school I guess.

Cardinal

I happened to like @SnoringFrog’s placement of Minimal-2D relative to Cardinal’s code. It’s a good location considering Cardinal doesn’t upset Retina, and it seemed to allow some interweaving with Minimal-2D. So when I set out to transplant Minimal-2D up to 2D land, I brought Cardinal along for the ride. There were a couple cosmetic changes to Cardinal though. First, I threw a > near the beginning of its statement #p x%>~~~+ +~*ttt*.x for Minimal-2D to change memory pointers within its loop/ Second, I shifted everything one character to the right to give Minimal-2D room to exit it’s loop gracefully. The p in this sting is for this character padding.

Befunge/98

The Befunges are actually where I started out trying to golf down the polyglot, since the C++ refactor changed all the other 2D lang code, except this one. In trying to learn WTF was going on in this code, I found this in the Begunge documentation:

The . command will pop a value off the stack and output it as a decimal integer, followed by a space, somewhat like Forth. , will pop a value, interpret it as the ASCII value of a character, and output that character (not followed by a space.)

Holy moley! We can clean up the null bytes on the output. After this, it was all just a matter of figuring out how to input the larger asci values, and segregating the code. Befunge-98 had a jump code ; telling it to skip over the [77*,68*,@ in ;[77*,68*,@;'1,'1,q, which gave us the segregation.

Befunge-98 also had a command (') to take the ascii code of the next character. So, '1, takes the code asci code for the character 1, puts it on the stack and then prints the ascii character for the top value on the stack with ,. Just gotta do this twice to print 11 and drop a q to quit out gracefully.

Befunge proper is a little less convenient, but only just. Here we have to perform a calculation to put the desired code on the stack. Fortunately, our codes were easily multiplied with 7*7 and 6*8 before the same output command,. Then we quit out of Befunge with @ before its older brother’s code contaminated the output.

Minkolang

After finding a fix for the Befunge’s trailing spaces I got pretty hyped up on the idea of finding a Minkolang fix too and Minkolang’s documentation said that output command that had been used up until this point worked in the same way as the Befunge Interpreter. O happened to be documented as another output command, that wasn’t described as sharing this Begunge-ness, so I just took a shot in the dark and tried outputting the string "3". Flawless Victory.

><>

One of the first things I looked at when moving the Minimal-2D code was verifying that I could move ><> along with it. If I was going to deal with 2D polyglot transversalism, I was going to deal with all transgressions. I basically luck sacked my way into the solution of putting ;n4 at the end of line 1 and moving the \D further back in line 1. BTW, I didn’t know that ><> could be directed down before answer 40 since it’s been so well contained. I’d like to think this could be used later to diverge ><> from another similar language.

Perl6

I’ve talked about some of Perl6’s <> balancing issues elsewhere in this answer, so I’m not going to go over it again. But I do want to point out that I moved #>27.say# to the second to last line. This doesn’t have a functional purpose in this answer. I actually made this move to satisfy a different answer that I ended up not using this round. I decided to just leave it since I plan to post that answer at my next opportunity and I didn’t want to bother undoing and re-doing it.

Bug Fixes

05as1e

05as1e definitely didn’t like the new Begunge code as much as the old version. I’d suppose it’s the ,s since that’s the only revolutionary character. In any event, I had to move the " further back in line two to hide the offensive commands, and I knew that the " had to go prior to the Befunge code path since " was a yes-op in both languages. (I can just make up terms like yes-op right?) Line 2’s 2-dimentionality is pretty rigid, but I was able to displace the < prior to Begunge’s code path with the ". The < however was a requirement of Perl6. (It has to have a < preceding all >s.) I was able to drop the < in line one at a location divined by instinct and foreknowledge resolving 05ab1e and Perl6’s disagreement.

Whirl

The Befunge changes on line 2 added an extra 1 to the polyglot prior to the Incident/Whirl line. This extra 1 caused Whirl to start off pointing to the wrong instructions on the wheel. The very first 1 in the C/C++’s preprocessor directive was only a line number reference in the code, and this could just as easily be any other line number, so I arbitrarily changed this to 4 to satisfy Whirl.

Incident

The detokenizing string at the end of the polyglot is well known at this point, so I won’t go into it. I removed from the string what I could and added the new tokens that were required. There are 2 detokenizing characters that are not in this string though that I should point out. First, the second R in #R+.----.R >]| is needed here because it’s a Fusion starting point, and it was safer on this line because there was already a Fusion starting point heading in the same direction. Second, the x in #= x is to remove a token involved in a ␉␊# pattern, which has become more common.

Others

Hexagony, Whitespace, and Prelude all had the usual minor adjustments, but nothing special worth talking about.

Final Thoughts

That’s all I’ve got for this answer. For those looking for a starting point on the next answer, I’d suggest evil. It seems workable, although I haven’t looked at it too closely, but I suspect it would not be too hard to integrate. I know it has a jump command that should help skip past the bulk of the polyglot. Good luck.

\$\endgroup\$
8
  • \$\begingroup\$ Fails in Incident (it prints 3333 then waits for input), but is likely easily fixable. The problem is that you've placed a token (-]) after the ^- token that was previously used to jump to the end of the program. The other two uses of -] are consecutive, so that forms a …xx…x… pattern, which is a backwards jump. Moving that last -] a little earlier (or the ^_s a little later, or both), though, is likely to be fairly easy. \$\endgroup\$
    – user62131
    Commented Feb 16, 2017 at 0:51
  • \$\begingroup\$ @ais523 Thanks. This is what I get for golfing while writing. Always remember to check the Incident kids. Fortunately I was able to fix this one with addition by subtraction, so overall win I think. \$\endgroup\$
    – Chance
    Commented Feb 16, 2017 at 8:01
  • 1
    \$\begingroup\$ If you run the V with -v (for verbose) you can replace a literal escape charater with <esc>, which might make working with the code in the future a bit easier. (I think) \$\endgroup\$
    – Pavel
    Commented Feb 19, 2017 at 22:22
  • \$\begingroup\$ Wow! Thanks @ais523 for the bounty. What a great way to start Monday morning! \$\endgroup\$
    – Chance
    Commented Feb 21, 2017 at 21:52
  • \$\begingroup\$ Befunge-98 is older than Befunge-93? \$\endgroup\$ Commented May 1, 2017 at 21:29
18
+600
\$\begingroup\$

183. Intel 8080 boot image (ZEMU), 9870 bytes

#16  "?63(o+?50;+'51;'  # #@ " /*"r"{\D-v e-'[fa5.q]PkPPX)\( 9 '#CO"14"^ 92                                       7 222222222222222222222222                                                             ##*/
#/*1&7//```"`    [>.>.]       )[-'][(7  >77*,68*,@'_      7 )(22)S    / \iiipsddpsdoh#####(#######??   #### ##  ######     ####         ###### # ####  #######     ####         ###### # ####  #######  a5# \7aa*+42@n; 7 999993 1 7 3 1 8 1 1 55 EEEEEδΘΔΔΔΘΔΘλa k zzzzkf kf k zzzzzd kf k zzzzza kf bfz coding=utf8 p''53'S^'                                                                                                          ! 1>?7ДOq#t#>2/Wr#t#t#q#68#r#t#t#68#q#63#r#t#t#6v#>#</Wr#6}#y/===Wr#7ЯOq#>J7Д/Wr#y<Wr#>5/Wr#t#t#6y#>-=/Wr#6|#>6/Wr122! 1退
#>x#z#111#y#y#y#_#0111118&1& 1111/"78"oo@         xxxxxxxxxxx        /112\     ##### #######   # #    ##### h#115#  o#    ##### ####  ###   #### #  # #####  #    ##### ####  ###   #### #  # #####  #    #
# 36!@`D  e ++++++::@                 L               R.----._      x-----x ########8=,_## ### ###### ######## #### ##### ####### ##### ###    # # #### ### ##### ####### ##### ###    # # #### ### ##### #
#comment -[af] xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # ##########  ### ## #####  ## #### ## # #####  ## ##### ####   ##### ## # ##  ## ####  ## ##### ####   ##### ## # ##  ## ####
#~==RtRtRtMbMbMbPSPSPS                                                       # ????!?!??!??!!!!???!?!??!!?!?!!!!!?!!!!?????!????????????????????!                                                           
#[#[]]QhQhQhQrQrQrHnHnHnbqbqbqLzLzLzQtQtQtTcTcTcRQRQRQ                       #
#<<<#++R++  ++++++++++++++++++++++++++++++++++++++++++U+++.._+++++++._       #
############################################################################## 4O6O@
 #-]+-}}[.^x+;;+;;+;;+<>;;+;;+;;+;;;;;;+;;+;;.._]}--<^>++[+++++[>+++++++<-]>._ ++++._+++._^<]+-+<[<<._>>>-]^>[<+++++[>++++++++++<-]>@@+.---@._+>][[
#{  
#=  
#*  
#cs  
#2""/*  
#9999 9 9
#9 999 99 9999 9
#9  
# 9 9999
#`<`(+?+?0l0v01k1kMoOMoOMoOMoOMOOx0l0ix0jor0h0h1d111 0eU0y0yx0moO1d0y0e0e00m1d0i0fx0g0n0n11yxMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmOotMOo0moo0n0tx0t0moO0f0t0gOOM0g0f0h0j0j0i000x1k1x0vx0v0l11110000011100^_)\\
[ "`e```.1'.0'.6''i]56pq\{}26q[puts 59][exit]" ,'_\['];#/s\\/;print"24"; exit}}__DATA__/
###x<$+@+-@@@@=>+<@@@=>+<?#d>;?\:-._++._++++._#/<?\>3-++._6+---2._#</++++++++++++++++++++++++++++++++++++++++++++++++._++._++++++.>!\
' wWWWwWWWWwvwWWwWWWwvwWWWwWWWW\WWWWwWWWWwWWWWW/WW\wWWWWWWWWwwwwvwWW/WwWWWWwvwWWwWWWwvwWWwWWWwvwWWwWWW ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho ho dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO dO MU ([])  ({}<(((((()()())){}{})){}{})>)(({})){}{(<(<()>)({})({}<{}>({}){})>){({}[()])}}({}){}({}()<()()()>)  (<><()>){({}[()])}{  # {((((((\';  a=$(printf \\x00);b=$(echo -n $a|wc -c);case $b[1] in 1*)echo 54;;4*)echo 78;;8*)echo 166;;*1*)echo 50;;*)echo 58;;esac;exit;#)';  print(( eval("1\x2f 2")and(9)or 13<< (65 )>>65or 68)-(0and eval("\"ppp\".bytes.class==Array and(4)or(95==\"ar_\"[2]and 5-96 or-93)"))^1<<(65)>>62) or"'x"or'wWW s'#}#(prin 45)(bye)46(8+9+9+9+9+=!)((("3'3)))"'a'[[@*3*74[?]* *]* * *(<\>]xxxxxxxxxxxxxxxxxxxxxxxx)'#\\
__DATA__=1  
#  
###;{a=1}={a:null};console.log a&&39||180
#  \\
""""  
#  
#  \
=begin  
#p :1*23!/5x%6E0 !|*****[[[828+*+@+*99]]]*****|!
;set print'-';print 89;exit#ss
[mxf]-main=-[165]- ###jxf*#p 173#*
p now 70 dollar off!
p has been selling out worldwide!
#PLACET,2<- #2FAC,2SUB#1<- #52FAC,2SUB#2<- #32FACREADOUT,2PLEASEGIVEUPFACs>>>
seeeemPaeue_ewuuweeee_eeeeeeCisajjapp_ppppxf⠆⠄⡒⡆⡘😆😨😒😨💬95💬👥➡😻😹😸🙀🙀😹😼😿🙀🙀😼😼😸🙀🙀🙀🙀  
👋🔢🌚🌝🌝🌚🌚🌚🌚🌚▲▲▲²²²²▲¡▼¡▲▲¡→  
밠밠따빠빠맣박다맣받다맣희맣희うんたんたんたんたんうんうんうんうんうんたんうんうんうんたんうんたんたんうんたんたんうんたんたんうんたんたんうんたんたんたんたんたんうんうんうんうんたんたんうんたんたんたんうんうんうんたんうんうんたんうんうんたんうんうんたんうんたんうんうんうんたんたんうんたんたんうんたんたんうんたんたんうんたんたんたんうんうん  
😊♈💖  
😇♈♈  
😊♉♈  
😇♈♈  
😇♈♉  
😇♈💜  
😊♉♈  
😊📢♈  
😈♈💜  
😊📢♈  
😇♉💞  
😊📢♉⠀⢃⠛⠋  
#-49,A,-1                              #
#-5,A,-1                               #
#6,A,-1                                #
1     ! !
2   !    !
1      !!
1  x*
53  ++-------+
1  x*|$0011 \|
51  +|/1000 /|
1  x*|\ 0011\|
34  +|/01 00/|
15  +|\ 0011\| R"12"R _* ?   ?@       _     !
1   *|@ 0110/| @  %"18" ?@    ?
1    |      +|            +   *
1   !+-------+---       ?  !  ?
1    !            <``=>  ? @ ?
<  <    <<   <  <
< B=  =====  =>8 =
, 8= > B    = =
=  ==  =    = >   8  =
D B+  +=   D  x   xxx x
` `    =   >  8  = >
 x ~   B  =   =  = = > ~
 B +   =  D+  ~ 8  = >x
x   x  x x      x  xx  x
x   x    x+   xx   x + +  +    +    +    <>
x    x xx     xx                +++   +   e$P+++++*D*+++1++1E!s
x+  +x +x     x + +      +  +
 8=+,  _         +    +   +         +
   +     +                +  +    +
 +             +  +  +      + + +    +
   +    +      +           +
   +    +      +          +    +      +
   +           +            +
   +      +  + +            +
   +       +   +            +
          +    +            +
# +   +                  +
#+     +     ++  +     +     +
#  +      +     +
+#
  *   +
  *+*

#  *************************************************+
# +  +
#          +                                       +
   +    + *
         *****+
# +       +
#   +        +
  * *
   +*****
#        +
 (printout t 164 )
(exit )  
#cepp  
MsgBox (0,"",169     )
#cs  
Yo::=~147
::=  
You can see an x here.<<<<
  
>{-<<<<<  
> 176
>> Output 1
>SET x TO 120. [0]{472454523665721469465830106052219449897}   @,-1,:*b5<>␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␌␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␌␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋␋
>X x. PPQ-}
>x--/2  
> =157;y=146--/2 
>main=print y{-ss s
  
\begin{code}  
{-x   ␉␉␉␉ 
␉
 ␉  



-}
open import IO;main = run(putStr"159" )
\end{code}
ppppppppppppp
out &49 &1
out &56 &1
out &50 &1

Take Northern Line to Tooting Bec
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Bank
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Embankment
Take Bakerloo Line to Embankment
7 UP
Take Northern Line to Mornington Crescent
7 RIGHT
7 RIGHT
7 TEACH
6 BOND
6 BOND
6 BOND
5 RIGHT
5 LEFT
5 RIGHT
7 BOND
7 TEACH
5 TEACH
6 YELL
5 TEACH
6 YELL
6 YELL
set ! 57,,...,,.,,..,,,,,,..,,,.$^
set ! 51.                         #"60"e.0,1,_ye do{--}gibe16"124"#8+*sizeString tnd xfmain=los*81''cagem x=4721en nd ogola=1ay $0C0 00 3cod/|puts_e
More 91 of this
How much is it
red down one blue up red down one blue up red up one red right two blue up sss
baa baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bleeeeeeeeeeeeet bleeeeeeeeeeeeet bleeeeeeeeeet baaaa bleet bleeeeeeeeeet bleeet bleeeeeeeeeet
wwWWWwWWWWWwWWWWWWWwWWWWWWWWppppp
When this program starts:
There is a scribe called x
x is to write 179

*/
#if 0
.int 2298589328,898451655,12,178790,1018168591,84934449,12597
#endif//*
#1""//*
#include<stdio.h>
#define  x(d) #d
#define u8 "38\0 "//"
char*x="24 10 31 1"
"a c #FFC0FF""B c #0000C0""d c #58007B""e c #0C8302"
"h c #E60001""i c #CAFFFF""j c #280000""k c #CA0000""l c #CA007F""n c #330001 ""q c #E60000"
"o c #FF8000""t c #FF00BC""u c #008080"
"A c #0040C0""E c #808000""F c #00C040""G c #008000 ""R c #800000"
"H c #0000AA""I c #00AA00""J c #55FFFF""K c #AAAAAA"
"r c red""g c green""b c blue""c c cyan""m c magenta""y c #FFFF00""x c black""_ c #FFFFFF"
"HHHahtdegggggggyrggggggc"
"IHHaixuEFbGGbggbryAEGRgc"
"JJHajyurbgbgggggggb____o"
"IJHakmyyyyyyyyyyyyyyyyye"
"I__almyyyyyyyyyyyyyyyyye"
"K__anmyyyyyyyyyyyyyy_y_e"
"HH_aqggyyyyyyyyg____m_Je"
"JH_axxxxxxxxxxxxxxxxxxxx"
"K__aaaam___bbbbbBm_bbBab"
"K__________bbbbb___bbxbb";//"
int f(char*a,char*b ){puts(a?"124":sizeof(0,u8)-5?u8"67":*u8""?"37":x(0'0  "'\"")[9]?"75":'??-'&1? "79":"77");}main(){f(x,x=0);}//<*/
#1""/*/
 
>import Text.Heredoc--WWWWWWWWWWWWWW<<W
>instance Num B where fromInteger _=B 170;negate _=B$x#x
>data B=B{u::Integer};g=[here|here<-"W>W"] --WWWWWWWWWW570rt Unc27<<[w|]
>x=1;y#a=128;x#a=174
>main=print$last$172:[u$[-1]!!0|g<"Z>"] --}
 
 console.log 178;
 
#1""/*/
#if 0
#endif//* --... ...--
/*/
p=sizeof(" (\");print'(''72'')';end!");main(){puts('??-'&1?"101":"92" );return 0;}
#if 0
#endif//* rk:start | print: "69" rk:end
print 61
#}
disp 49
#{
}{}<>        K yya+-        &  g+$
$'main'3x             A=AgRA;       AC
#-3o4o#$$$
#<T>"3"O._</+++++++>/+++<-\>+++.---.\_<!+++++++++++++++++++++++++++++++++++++++++++++++++._++.-.>@
#<<<#>>>  /
reg end="";print(85);reg s#++++++++++++++++++++++++++++++++++++++++++++++++++++++++.-.
=end
;"""#"#xxxxclou"78"<\++++>/<~#class P{function:Main(a:String[])~Nil{83->Print();}}
#endcOmment
#nocOmment outtext("155")
#ce pS9^7^8^MUOUOF @0:8:8      \    @,,1'1'<> @125iRE
#p|o51~nJ;#:p'34'3             \=# print(size([[1] [3]][1,:]   )[1]==2?158+4:17)#>say 27#>>>say 170-3#]#print(47)#]#echo 21#>/#print(171)#s-#print 175#s
#8M`|   <esc>dggi2<esc>//      $}<}}<}>}[<< }<<<<<}<<}<<<<}<<<}}}<}}<}}<}     }<}}<}}<}}}<}}<<<<<<<<<<<}}}<}}<}}<}}<}}<}}<}}}<<<<<<<<<<}+++++++++++++++++++++++++++++++++++++++++++++++++._++.._#]~-<~-<~-<<<~-<COprint("65")#`=>ass^_^_#
#9 "25"   +/pppppppx     eeee*n*n*n*es*s*s*^ee*n*n*n*e*sss*e*n*n*n*ee*s<* 5>1  e*///\)Q222999686#

Try it online!

Explanation

Thanks to Potato44 for the idea to add machine code, it was a lot of fun to make this answer.

I didn't do CP/M COM file because it restricts the size of polyglot to about 60KB which I want to avoid. Boot image turned out even easier to do than COM because ZEMU loads boot sector from 6th sector by default (1-based, 128 byte logical sectors), so start of polyglot does not need to be executed. The boot code must be at offset 0x280 ((6-1)*128) in the polyglot.

I use ZEMU emulator which is linked from this page. To run polyglot in ZEMU:

  • Disks > A: select polyglot file
  • Options > Instruction Set I8080
  • Press Boot button

Function that prints one char to console (cns$ot) was copied from BIOS22Dv221.ASM from ZEMU distribution. I made two changes: character is not masked to 7 bit ASCII because we control parameters and jrz cns$ot is replaced with jz cns$ot because jrz (jump relative if zero) is Zilog Z80 instruction not present in Intel 8080.

Initial program (Intel syntax, assembler linked from here):

    org 3120h    ; chosen so that cns$ot == 0x3131, easier to generate
                 ; this program will be generated at this offset
                 ; to run it directly specify org 0100h

    mvi c,31h    ; '1'
    call cns$ot
    mvi c,38h    ; '8'
    call cns$ot
    db 38h       ; for answer 188, NOP in I8080
    mvi c,33h    ; '3'
    call cns$ot
    hlt          ; halt processor

;;;;;;;;; copied from BIOS22Dv221.ASM
cno$sp equ 7dh
cno$sb equ 01h
cno$si equ 00h
cno$dp equ 7ch

; print char to console, receives char in c register
cns$ot:
    in cno$sp    ; in status
    xri cno$si   ; adjust polarity
    ani cno$sb   ; mask status bit
    jz cns$ot    ; repeat until ready
    mov a,c      ; get character in a
    out cno$dp   ; out character
    ret

This program contains chars that cannot be used directly in polyglot. Most ASCII control chars (code < 0x20) are prohibited in Simula, non-ASCII chars (code >= 0x80) cannot appear alone because the file must be valid UTF-8. So the above program is generated by another program that is valid UTF-8.

The following program generates needed code and jumps to it. ld (hl),a cannot be used because of Grass ('w'==0x77). sub h (0x94) and xor a (0xAF) are UTF-8 continuation bytes, they must be prepended with UTF-8 lead byte. Instruction ret nc (=0xD0, return if not carry) is used as UTF-8 lead byte. To make it do nothing it is preceded with scf instruction (set carry flag). Also avoided ',' (0x2C) and '.' (0x2E) for DOBELA. org 0100h directive is not used because used assembler does not understand it (org is set in the GUI). This program is position independent anyway. I like Zilog mnemonics more, so I used them for longer program.

Zilog syntax, assembler linked from here:

  ; generate: 0E 31 CD 31 31 0E 38 CD 31 31 38 0E 33 CD 31 31 76 DB 7D EE 00 E6 01 CA 31 31 79 D3 7C C9

  ld hl,3120h

  ld a,3Fh
  scf       ; set carry flag so that ret nc does nothing
  ret nc    ; utf8 lead byte for next insn
  sub h     ; a -= h; a = 0Eh;  utf8 cont byte (opcode 0x94)
  ld c,a

  ld (hl),c ; 0Eh    ; not using ld (hl),a because it is 'w'
  inc hl

  ld (hl),h ; 31h
  inc hl

  ld a,32h
  cpl       ; a = ~a; a = 0xCD
  ld d,a
  ld (hl),d ; CDh
  inc hl

  ld (hl),h ; 31h
  inc hl
  ld (hl),h ; 31h
  inc hl

  ld (hl),c ; 0Eh
  inc hl
  ld (hl),38h ; 38h
  inc hl

  ld (hl),d ; CDh
  inc hl
  ld (hl),h ; 31h
  inc hl
  ld (hl),h ; 31h
  inc hl

  ld (hl),38h ; 38h
  inc hl

  ld (hl),c ; 0Eh
  inc hl
  ld (hl),33h ; 33h
  inc hl

  ld (hl),d ; CDh
  inc hl
  ld (hl),h ; 31h
  inc hl
  ld (hl),h ; 31h
  inc hl

  ld (hl),76h ; 76h
  inc hl

  ld a,23h  ; not using ld a,24h because it has '$' (breaks SNUSP)
  inc a
  cpl       ; a = ~a; a = 0xDB
  ld d,a
  ld (hl),d ; DBh
  inc hl

  ld (hl),7Dh ; 7Dh
  inc hl

  ld a,c    ; a = 0Eh
  cpl       ; a = F1h
  dec a
  dec a
  dec a     ; a = EEh
  ld d,a
  ld (hl),d ; EEh
  inc hl

  scf
  ret nc
  xor a     ; a ^= a; a = 0; utf8 cont byte
  ld c,a
  ld (hl),c ; 00h
  inc hl

  ld a,4Ah
  scf
  ret nc
  sub h     ; a -= h; a = 0x19;  utf8 cont byte
  cpl       ; a = ~a; a = 0xE6
  ld d,a
  ld (hl),d ; E6h
  inc hl

  ld a,c
  inc a
  ld d,a
  ld (hl),d ; 01h
  inc hl

  ld a,35h
  cpl       ; a = 0xCA
  ld d,a
  ld (hl),d ; CAh
  inc hl
  ld (hl),h ; 31h
  inc hl
  ld (hl),h ; 31h
  inc hl

  ld (hl),79h ; 79h
  inc hl

  ld a,2Dh  ; not using ld a,2Ch because it has ','
  dec a
  cpl       ; a = 0xD3
  ld d,a
  ld (hl),d ; D3h
  inc hl

  ld (hl),7Ch ; 7Ch
  inc hl

  ld a,36h
  cpl       ; a = 0xC9
  ld d,a
  ld (hl),d ; C9h

  ld sp,3232h  ; set up stack for generated program

  ld hl,3120h  ; not using ld l,20h because it has '.'
  jp (hl)      ; go to generated program 
               ; confusing mnemonic - actually it is jp hl, ie. PC = HL
               ; opcode 0xE9, utf8 lead byte (0xE9 = 0b11101001), must be followed by 2 cont bytes
  db 80h,80h

This program is assembled into:

! 1>?7ДOq#t#>2/Wr#t#t#q#68#r#t#t#68#q#63#r#t#t#6v#>#</Wr#6}#y/===Wr#7ЯOq#>J7Д/Wr#y<Wr#>5/Wr#t#t#6y#>-=/Wr#6|#>6/Wr122! 1退

It must be at offset 0x280 in the polyglot (see line 2). Abstraction test in the test driver checks that.

Refactorings

Shells

Moved shells back to longest line. I like this layout more because parens don't get aligned with other langs. Moved Moorhenses and Flaks before shells, so they don't break when shells are changed. Longest line has this layout now:

Grass  Moorhenses  Flaks  Shells  Rubies/Pythons/Perl5  PicoLisp  Prelude  Klein001

New shells code:

a=$(printf \\x00)
b=$(echo -n $a | wc -c)
case $b[1] in 1*)echo 54;; 4*)echo 78;; 8*)echo 166;; *1*)echo 50;; *)echo 58;; esac
exit

Old shells code:

a=$(printf \\x00)
b=${#a}
case "{"$ar[1]"}"${b} in *1)echo 54;; *4)echo $((19629227668178112600/ 118248359446856100));; *1*)echo 50;; *)echo 58;; esac
exit

Length of $a is calculated by $(echo -n $a | wc -c) now (from here). Initially I used this to get rid of #, but now it is used because of shorter code. Shells can contain # because Flaks are before shells.

Yash (166) uses built-in echo command which does not support options by default, so "-n " and linefeed end up being part of the output, which gives additional 4 bytes. When not set ECHO_STYLE defaults to SYSV (-n option is not accepted).

This TIO link tests code in all shells.

Additional ((((( before shells fix Underload and Retina. One more pair of parens is added to hide 58 from Prelude (closed with #) after exit). { before (((((( is for Japt, without it Japt hangs.

Flaks

Due to relocation of Flaks starting code can be simplified – only ([]) is left:

     line 21      (Grass(([5]{})))    scripting langs                  clear stack     Flaks main code                                                                                      begin skip code      the rest of polyglot   end skip code   print(85)
old: []{}[][][]   ((([]{})))          ((()()<<()>>)((()([])))<<()>>)   {}{}{}{}{}{}{}  ({}<(((((()()())){}{})){}{})>)(({})){}{(<(<()>)({})({}<{}>({}){})>){({}[()])}}({}){}({}()<()()()>)   (<><()>){({}[()])}{           ...           }{}<>              ()
new: []{}[][][]     ([]  )                                                             ({}<(((((()()())){}{})){}{})>)(({})){}{(<(<()>)({})({}<{}>({}){})>){({}[()])}}({}){}({}()<()()()>)   (<><()>){({}[()])}{           ...           }{}<>              ()

This TIO link tests code in all Flaks.

Fission & Cardinal

Fission was moved into LNUSP: R"12"R _*. Second pointer is used to terminate Fission as soon as possible – on 3rd step, see answer 54 for more info.

Cardinal was moved into LNUSP: @ %"18". As in Fission, second pointer is used to terminate Cardinal as soon as possible – on 3rd step.

MarioLANG

Use ####... instead of ====... as a platform:

enter image description here

Minimal-2D

Polyglot with MarioLANG:

enter image description here

Wierd & 1L_a

Wierd: use space at line 10 column 79 to reflect IP.
1L_a, Wierd: space at line 9 column 79 is important.

enter image description here

Cubically

New code: :1*23!/5x%6E0

:1*23!/5x%6E0
! - skip over / in Klein 201
x - destroy Cardinal pointer before it hits /

pure:
:1*23/5%6E0

faceval:
0 0
1 9
2 18
3 27
4 36
5 45

program:
:1   mem = 9
*23  mem *= 18; mem *= 27
/5   mem /= 45
%6   print mem
E0   exit

9*18*27/45 == 97 (integer division)

6 in %6 is used to print mem because 0-5 are used to print faceval (eg. %3 prints 27)
0 in E0 is not an exit code, it is present just to trigger E instruction

Klein 201/100

New code: !|*****[[[828+*+@+*99]]]*****|!

After all the multiplications stack contains a single zero because popping from empty stack gives zero. This zero is added to the main number with + next to @. Previously it was discarded with ?, see Klein 001 answer.

How doors work in Klein:

enter image description here

Whirl

Whirl code is basically the same, the only change is that main code assumes that current operation is ops.one (2), not ops.load (4).

Effectively Whirl can be thought of as having 3 operations:

  • 1 rotate one step
  • 0 switch rotation direction
  • 00 execute current instruction and switch ring

Combined operations to simplify reasoning about program:

  • 0000 if current op of inactive ring is noop then just execute current op of active ring without any side effects
  • 11..11 rotate n steps
  • 011..11 switch direction and rotate n steps

0000 executes current instruction of active ring, but also executes current instruction of inactive ring as a side effect. If current instruction of inactive ring is harmless then we can just focus on operations on active ring without thinking what is happening with inactive ring. This is especially useful with this program because it has clear separation: first the number 32 is created using only math ring and then we switch to ops ring and execute 2 instructions there (print and exit).

First I wanted to have current operation on ops ring to be noop when main code starts executing. It has 2 advantages: 1) main Whirl code can be executed standalone and 2) we can completely forget about ops ring when creating number 32 with math ring. However, it makes code longer than it was, so instead main code assumes that current operation is ops.one (2). It means that ops.value is set to 1 as a side effect of math operations, which then is used for printing. Old code achieved the same effect with ops.load instruction, but using ops.one more clearly expresses the intention – to set ops.value to nonzero.

at this point current ring is ops, dir = clockwise, cur op = ops.one
00    switch to math ring
011   rotate to math.not
0000  math.not (math.val = 1)
01111 rotate to math.store
0000  math.store (mem[0] = 1)
1     rotate to math.add
0000  math.add (math.val = 2)
01    rotate to math.store
0000  math.store (mem[0] = 2)
011   rotate to math.mult
0000  math.mult (math.val = 4)
0000  math.mult (math.val = 8)
0000  math.mult (math.val = 16)
0000  math.mult (math.val = 32)
011   rotate to math.store
00    math.store (mem[0] = 32), switch to ops ring
up to this point the program is the same as before

01111 rotate to ops.intio
0000  ops.intio - print mem[0] as number
0111  rotate to ops.exit
00    ops.exit

New code is shorter because old code has a couple of redundant direction switches in second part of the program, not because of new assumption.

old: (1111) 00011000001111000010000010000011000000000000000001100 01111110000011100
new: (11)   00011000001111000010000010000011000000000000000001100   011110000011100

How to keep Whirl correct when changing something before Incident/Whirl line:

  • ensure there are even number of 0s before main Whirl code
  • ensure there are no two consecutive 0s
  • add/remove enough 1s until Whirl works again; adding n 1s is equivalent to removing 12-n 1s and vice versa

I unknowingly broke first rule when added Ropy. When there are odd number of 0s main code starts executing with incorrect direction of ops ring which breaks exit instruction. So now there is 0 on line 3 which compensates 0 on line 1.

Others

CoffeeScript: console.log a&&39||180 (from here)

INTERCAL: moved to line 37
Brainfuck, Agony: moved to other brainfuck derivatives on line 10

xEec: moved into 1L_a (h#115# o#)

CSL: moved to line 80
Trefunge: moved to line 120
Gaot++, Stones: placed on separate lines

\$\endgroup\$
1
  • 4
    \$\begingroup\$ Nice, that is a lot of bytes to golf off. \$\endgroup\$
    – Potato44
    Commented Mar 10, 2018 at 19:18
17
\$\begingroup\$

15. Haystack (141 bytes)

#v;2^0;7||"<+0+0+0+<*!2'!1'L#'1r'4;n4
#v0#_q@
#>3N.15o|1
#|\w*
#8  ^1b0<
#|
#M`
print ((0 and'13')or(None and 9 or 1/2 and 1 or 5))
#jd5ki2

Note: there is an ESC after o in the third line and after j in the last line

This prints 1 in Python 3, 2 in Vim, 3 in Minkolang, 4 in <><, 5 in Python 2, 6 in SMBF, 7 in Japt, 8 in Retina, 9 in Perl, 10 in Befunge, 11 in Befunge-98, 12 in Fission, 13 in Ruby, 14 in turtlèd, and 15 in Haystack.

Try it online!

Explanation

#v                           go down
 v
 >                           go right
  3N.                        does nothing important
     15o|                    outputs 15 and ends program
                             there is an <ESC> after 'o' since 'o' in Vim enters insert mode
         1                   I added this to satisfy Retina
\$\endgroup\$
7
  • \$\begingroup\$ Awesome, thanks for checking out Haystack! :) \$\endgroup\$
    – Kade
    Commented Dec 7, 2016 at 13:51
  • \$\begingroup\$ @Kade It's a nice 2D language, an online interpreter would be more helpful (although I have already downloaded the Python interpreter) :) \$\endgroup\$
    – user41805
    Commented Dec 7, 2016 at 14:13
  • \$\begingroup\$ @Kade There is a TIO link for haystack now! \$\endgroup\$
    – user41805
    Commented Dec 8, 2016 at 5:47
  • \$\begingroup\$ @MistahFiggins The link works for me and outputs 15 \$\endgroup\$
    – user41805
    Commented Dec 8, 2016 at 5:58
  • \$\begingroup\$ @MistahFiggins Cache? Because it works for me without any problems or any error messages \$\endgroup\$
    – user41805
    Commented Dec 8, 2016 at 6:00
17
\$\begingroup\$

9. Perl, 84 bytes

#v;7||"<+0+0+0+<;n4
#>3N.
#|\w*
#8
#|

#M`
print(None and 9or 1/2and 1or 5)
#j␛d5ki2

There's a literal ESC character in the actual code between the j and d; it has been replaced with a ␛ here for visibility.

This prints 1 in Python 3, 2 in Vim (tested locally, but here's a link for the very similar language V), 3 in Minkolang, 4 in <><, 5 in Python 2, 6 in SMBF, 7 in Japt, 8 in Retina, and 9 in Perl.

Let's get some more exoteric languages in, via abusing arithmetic that works differently in different languages. (None is falsey in Python but truthy in Perl, and and/or chains work the same way in both languages.)

Apart from Python, I also had to change the vim code. Instead of making it into a series of no-ops, I just let it insert junk, then deleted the junk again at the end.

\$\endgroup\$
9
  • 4
    \$\begingroup\$ Seriously? You're going to make it extremely difficult for anyone else to create answers if you put in a literal ESC. We have to be able to test the code. \$\endgroup\$
    – mbomb007
    Commented Dec 6, 2016 at 22:55
  • 1
    \$\begingroup\$ You don't have to include the literal ESC in your own answers; I just found it to be the easiest way to write this one. (Additionally, it works fine in Firefox, and in local testing; the only thing blocking me from putting it in the post is that Chromium, which I use for SE, doesn't want to put it into the input box.) \$\endgroup\$
    – user62131
    Commented Dec 6, 2016 at 22:58
  • 1
    \$\begingroup\$ Also, you can't test locally for Vim. Languages are defined by the interpreter that is used. So it's really V that we've had all this time. \$\endgroup\$
    – mbomb007
    Commented Dec 6, 2016 at 22:59
  • 1
    \$\begingroup\$ Err, isn't vim an interpreter for Vim? (It works in both vim and V, though.) \$\endgroup\$
    – user62131
    Commented Dec 6, 2016 at 22:59
  • 4
    \$\begingroup\$ @ais523 maybe you can put ␛ to represent the 0x1B byte? \$\endgroup\$
    – betseg
    Commented Dec 7, 2016 at 5:49
17
\$\begingroup\$

6. SMBF, 45 bytes

#v<++++<;n4
#>3N.
print('1'if 1/2else'5')
#i2

Try it online

This program prints 1 in Python 3, 2 in V, 3 in Minkolang v0.15, 4 in ><>, 5 in Python 2, and 6 in SMBF.

SMBF (aka Self-modifying Brainfuck) uses <++++<>.. The pointer is moved left (to the last character of the source code), and the cell is incremented four times then printed.

\$\endgroup\$
0
16
\$\begingroup\$

13. Ruby (129 bytes)

#v;2^0;7||"<+0+0+0+<*!2'!1'L;n4
#v0#_q@
#>3N.
#|\w*
#8  ^1b0<
#|
#M`
print ((0 and'13')or(None and 9 or 1/2 and 1 or 5))
#jd5ki2

Please note the literal Esc character on the last line between the j and d, as per ais523's Perl answer.

Try it online!

This prints 1 in Python 3, 2 in Vim, 3 in Minkolang, 4 in <><, 5 in Python 2, 6 in SMBF, 7 in Japt, 8 in Retina, 9 in Perl, 10 in Befunge, 11 in Befunge-98, 12 in Fission and 13 in Ruby.

Just a minor modification to the existing print statement to abuse the fact that 0 is truthy in Ruby. I had to add some spaces to the other statements to make it parse correctly.

\$\endgroup\$
16
\$\begingroup\$

16. Pyth (159 bytes)

#v\;2^0\;7||"<+0+0+0+<*!2'!1'L#'1r'4;n4
#v0#_q@
#>3N.15o|1
#|\w*
#8  ^<1b0 <
#|
#M`
print ((0 and'13')or(None and 9 or 1/2 and 1 or 5))
#"07|5//00;16 "jd5ki2

Note: there is an ESC byte (0x1B) after the o in the third line and after the j in the last line.

This was quite a fun experience. Japt and Pyth are both golfy languages, but Japt is infix and Pyth is prefix, and Pyth auto-requests input and fails if arguments are missing.

Before the Haystack answer I had an almost-working solution using #, which gets a char code in Japt and loop-until-error in Pyth. Pyth happens to be very useful in polyglots, since the common comment char # essentially works as an error silencer.

When I got home I managed to find a this piece of code that worked in both using //, which works as a comment in Japt and two divisions in Pyth. Then it was just a matter of getting the Befunges to route correctly.

This is very unlikely to be optimal, but it's good enough for now. I tried to test them all, but I'd highly appreciate someone double checking that the outputs match.

Prints 1 in Python 3, 2 in V, 3 in Minkolang, 4 in ><>, 5 in Python 2, 6 in Self-Modifying Brainfuck, 7 in Japt, 8 in Retina, 9 in Perl, 10 in Befunge(-93), 11 in Befunge-98, 12 in Fission, 13 in Ruby, 14 in Turtléd, 15 in Haystack, and

16 in Pyth.

Explanation

What Pyth sees here is:

#v\;2^0\;7||"string
multiline
string"07|5//00;16 "string

This translates to the following pseudocode:

while no errors occur:
    evaluate ";"
    print 2
    print 0 to the power ";"
    print 7
    print "string\nmultiline\nstring" or 0 or 7
    print 5 or 0 divided by 0 divided by (missing)
print 16
do nothing with "string"

The first loop exits on trying to evaluate ; which isn't a valid expression. Then Pyth just prints 16.

\$\endgroup\$
2
  • \$\begingroup\$ Extending in what way? I still need another 5 or so bytes available for my answer ;) \$\endgroup\$ Commented Dec 7, 2016 at 12:48
  • \$\begingroup\$ @AlfieGoodacre By adding the rest of the details to the post. I just wanted to remain sane and thus posted my code before anyone stole my place. :D \$\endgroup\$ Commented Dec 7, 2016 at 12:51
1
2 3 4 5
16

Your Answer

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