title: When was this language released?

text:
# Question
Title: When was this language released?
Your challenge is simple. You need to write a program that prints to either STDOUT or a file the year the language it is written in was released. Because this is such a simple task, the twist is that it must be written in as many different languages as possible.

Your score is the total number of different years that are correctly printed.

For each language you use, you must

* Specify which version of the language you are using. (If there are multiple versions)
* Specify what year that version was first released, and
* Provide a link to a page proving the date of your version/language.

Any one of these counts as release date proof, as long as it specifies the version number (if applicable) and a release date.

* A wikipedia page.
* An esolangs page.
* The language's official website. A github page or similar counts, as long as it has a release date. (Latest commit does not count, unless there is a version number somewhere in the code)

If there are not multiple versions or releases of a language, just use the initial release date of the language.

Minor versions of the same language *do* count as different languages, as long as they come from different years and still produce the correct output. You may *not* use any builtins that give you information (including release date) about the current version of the language you are using. For example, this is an invalid python submission:

```
import platform
i = platform.python_version()
if i == '3.5':
    print(2015)
if i == '3.4':
    print(2014)
if i == '3.3':
    print(2012)
...

```

Whichever submission correctly prints the most distinct years wins!

# Rules

* Each program must print out the language year *and nothing more*. A trailing newline (windows style or \*nix style) is allowed.
* No programs may take any input.
* In case of a tie, the shortest code scored in bytes wins. You may use whatever encoding you like for this, but all programs must use the same encoding.
* Any of the programs may print to STDERR, or throw runtime/compile time errors and warnings *as long as* the correct output is still printed to STDOUT or a file.
* Different languages may use different IO methods, but they most all be full programs, (functions not allowed for this challenge) and follow one of our default IO methods allowed.

Happy ~~golfing~~ polyglotting!

# Answer
> 172 votes
## A Brief History of 2D Programming Languages: 16 (+2) years

```
v19977/2{@{{4{\_______>/02&&&#????        *    P+++++1P1P-1P+1E     *                         *
\'\02'oo100@n590@n;                       *                         *                         *
>"8991",,,;5-;,@                          *                         *                         *
   *                                      *                         *                         *
  \ *              ++++++++++++++++++++++++  ++++++++++++++++++++++++  ++O--OO++++++++OX*******      *
     *   #2018O@       *                  *      *                  *      *                  *      *
      *                *                  *      *                  *      *                  *      *
       *               *                  *      *                  *      *                  *      *
        *           ****    ****          *   ****    ****          *   ****    ****          *   ****    *****
         *         *   *   *    *         *  *   *   *    *         *  *   *   *    *         *  *   *   *
          *        *   *  *      *        *  *   *  *      *        *  *   *  *      *        *  *   *  *
           *      *    * ****     *       * *    * ****     *       * *    * ****     *       * *    * ****
            *     *    *     *            * *    *     *            * *    *     *            * *    *     *
R"2014";     *****      *******       ******      *******       ******      *******       ******      *******

 x
x%"2010"x
 x

$'main'        \/\/\/\
 \-[2005]o-#   \++++++\
               /++++++/
               \++++++\
               /++++++/
               \/\/\/\++.--..+++.#

S1^2^2^6^8MAOUOAOOF

      /K:0:1:@

  >      "7102"4&o@

|        }+++++[>++++++++++<-]>.--..++++++.@

```

Did I mention that I like 2D programming languages?

### 1993: Befunge

The language that (allegedly, see the last section) started it all. In Befunge, you can redirect the control flow with `<v>^`, but the now ubiquitous mirrors `\` and `/` weren't a thing yet. The Befunge interpreter used on Anarchy Golf ignores unknown commands. We can use this to distinguish the Befunge family from the \>\<\> family. Hence, the code executed by Befunge is this:

```
v
\
>"8991",,,;5-;,@

```

The `"8991"` pushes the individual characters onto the stack. `,,,` prints the first three of them. Then `;` is unknown (which we'll use to distinguish it from Befunge 98), `5-` turns the `8` into a `3` and `,` prints that as well before `@` terminates the program.

### 1997: Wierd

Writing this part of the solution took me probably as long as writing all the others *and* fitting them together...

Wierd only knows two symbols: space, and everything else. The instruction pointer tries to follow the path formed by the non-space characters, starting diagonally from the top left corner and always trying to go as straight as possible. The bends in the path form the actual instructions (with the degrees of the turn determining which instruction to execute). So the code seen by Wierd is this:

```
v1997                                     *                         *                         *
 '                                        *                         *                         *
  8                                       *                         *                         *
   *                                      *                         *                         *
    *              ++++++++++++++++++++++++  ++++++++++++++++++++++++  ++O--OO++++++++OX*******      *
     *                 *                  *      *                  *      *                  *      *
      *                *                  *      *                  *      *                  *      *
       *               *                  *      *                  *      *                  *      *
        *           ****    ****          *   ****    ****          *   ****    ****          *   ****    *****
         *         *   *   *    *         *  *   *   *    *         *  *   *   *    *         *  *   *   *
          *        *   *  *      *        *  *   *  *      *        *  *   *  *      *        *  *   *  *
           *      *    * ****     *       * *    * ****     *       * *    * ****     *       * *    * ****
            *     *    *     *            * *    *     *            * *    *     *            * *    *     *
             *****      *******       ******      *******       ******      *******       ******      *******

```

The `1997` at the top isn't actually executed, but Wierd lets us read it from the source code, which is a *lot* shorter than trying to construct the character codes for the four digits itself (even if it doesn't look like it...). I don't feel like breaking this entire thing down, but you can clearly see the four repeated sections. What this does is that we first store `1` on the stack and then each of those four sections increments this `1`, and then branches. The bottom branch pushes another `1`, retrieves the source character at these coordinates and prints it, whereas the top branch is redirected to the next section. You might wonder why the ends of the paths are so unnecessarily long, but that's because when Wierd hits the end of a path it tries to jump to a nearby path before deciding that it should terminate the current branch. To avoid this, we need to move these ends sufficiently far away from any other code.

### 1998: Befunge 98

Befunge got a fairly well-known update in 1998 with a very rigorous spec that can be generalised to arbitrary dimensions (and I think also arbitrary topologies). It's largely backwards-compatible with Befunge though, which makes it fairly easy to polyglot the two. This Befunge still didn't have any mirrors, so the executed path is the same as for Befunge 93:

```
v
\
>"8991",,,;5-;,@

```

The difference is that Befunge 98 doesn't ignore the `;`. Instead it acts a bit like a comment in that all commands until the next `;` are ignored. This way, we don't decrement that `8` to `3` and print the `1998` as is.

### 2001: ~~A Space Od...~~ PingPong

2001 is the year of Piet, but I really didn't feel like polyglotting an image file with all the other programs, so here is a lesser known 2D language. It seems to have quite a lot of features (which we're not going to use). Thanks to Sp3000 for finding the original interpreter (which is the only dead link on the archived version of the official website).

PingPong is somewhat unusual in that it has *only* mirrors and no `<v>^` redirectors. So this moves through the `v19977` at the start and then hits the mirror which wraps it to the bottom. The relevant code is then:

```
v19977/

...

      /K:0:1:@

...

```

The actual code is quite simple: `K` pushes `20`, the digits push themselves, `:` prints an integer and `@` terminates the program.

### 2003: SNUSP

This is first language where things get a bit easier, because SNUSP supports an explicit entry point. That entry point is marked by `$`. Judging from some articles on esolangs, this language has inspired several others, but unfortunately, at the end of the day it's just a Brainfuck derivative. That said, I think the way this sets the current cell to 48 is quite neat (and was stolen from the esolangs article). Here is the relevant part of the code:

```
$'main'        \/\/\/\
               \++++++\
               /++++++/
               \++++++\
               /++++++/
               \/\/\/\++.--..+++.#

```

Those are 24 `+`s and the mirrors send the IP through each one exactly twice.

### 2004: Axo

For whatever reason, this language *does* have the `<^>` redirectors but instead of the usual `v` it uses `%`. Hence this just moves across the first line. The relevant code is:

```
v19977/2{@{{4{\

```

We push a few digits to begin with, perform a division. Then `2{` prints the `2`, `@` clears the stack. `{{` prints two (implicit) `0`s. `4{` prints the `4` and `\` terminates the program.

### 2005: Rail

2005 was a difficult choice. For no other year did I find as many 2D languages, and there is ADJUST and Archway, both of which start in the *lower* left corner (which would have made them easy additions). I like Rail though and since it has an explicit entry point is wasn't hard to add either. Rail looks for a line start with `$'main'` and starts moving south-east from the `$`. That means the relevant code is:

```
$'main'
 \-[2005]o-#

```

The `\` and `-` are just tracks (no-ops). The `[2005]` is a string literal which `o` prints before `#` terminates the program.

### 2006: BestFriends.js

A two-dimensional Brainfuck. There is another interesting language for this year called Black, which starts at coordinate `(3,3)` (1-based) which would have made using this in a polyglot interesting, too. I couldn't find an interpreter though. So we'll have to work with another BF-derivative instead...

The interesting thing about this one is that it doesn't format the grid into lines with linefeeds like most other 2D languages. Instead `|` is used as the line separator. Since I didn't use `|` for any other languages, I could simply put a `|` on the last line which makes the entire rest of the program a single line as far as BF.js is concerned. The relevant code is then this (turning the `|` into an actual linefeed):

```
v19977/2{...
        }+++++[>++++++++++<-]>.--..++++++.@

```

BF.js uses *neither* `<v>^` nor mirrors. The only ways to redirect control flow is with `{}` which turn the IP direction by 90°. So those braces move the IP to the second line. The remainder is a plain Brainfuck solution (not particularly well golfed) that sets a cell to `50` (code point of `2`) and then prints `2006` by shifting the value around a bit. `@` terminates the program.

### 2008: BrainSpace 1.0

For this year I really wanted to use DOBELA which uses multiple entry points and looks like the lovechild of Fission and Ziim. Unfortunately, I haven't been able to get the interpreter to work. So here is another BF derivative (the last one, I promise).

As opposed to the last one, this one knows *both* `<v>^` and mirrors, so the relevant code is:

```
v
\'\
  8

  \ *              ++++++++++++++++++++++++  ++++++++++++++++++++++++  ++O--OO++++++++OX

```

This one doesn't have the usual BF-style `[]` loop (instead you'd need to form an actual 2D loop), so I just decided to hardcode the `50` since I had a ton of characters in a row from Wierd anyway. Note that the `'` and `8` are ignored, the `*` is a conditional trampoline which we can ignore and the `O` is Brainfuck's `.`. The `X` terminates the program.

### 2009: \>\<\>

Probably the most popular Fungeoid (other than Befunge itself) at least around these parts. \>\<\> has both `<v>^` and mirrors but also string literals, so the executed code is this:

```
v
\'\02'oo100@n590@n;

```

The string literal mostly serves to skip the `\` we used for BrainSpace 1.0 but while we're at it we might as well push the first two characters. `oo` prints them. Then `100` pushes three digits, `@` shoves the top one to the bottom and `n` prints the `0` underneath. We do the same thing again with `590` which prints the `9`. If you're wondering why I'm not just printing `2009` as is, wait for 2015. `;` terminates the program.

### 2010: Cardinal

This one was simple, because it has an explicit entry point at `%`. However, this one creates 4 IPs in all directions (hence the language name, I suppose), and we need to get rid of 3 of them. Here is the relevant code:

```
 x
x%"2010"x
 x

```

Well, yeah. (In Cardinal, string mode prints directly instead of pushing the characters onto a stack.)

### 2011: RunR

Another language with an explicit entry point (by David Catt who has created a few other very nice esolangs), this time at `S`. This makes the relevant code this part:

```
S1^2^2^6^8MAOUOAOOF

```

RunR is a bit interesting because most operations work with a sort of register and values need to be moved to the stack explicitly for binary operations. The digits set the register values to themselves and `^` pushes the current register to the stack. Then `M` is multiplication (register times value popped from stack), `U` is subtraction, `A` is addition, `O` is output. `F` terminates the program.

### 2012: Ropy

Like Wierd, Ropy tries to follow sections of non-space characters, but here the bends don't determine the commands. In fact, it turns out that Ropy is more similar to my own Labyrinth in that the chosen direction depends on the top of the stack. However, we don't really need to worry about that here, because Ropy just moves along the first line:

```
v19977/2{@{{4{\_______>/02&&&#????

```

There's a lot of stuff we can ignore up to the `>`. All we need to know is that the top of the stack will at that point be a `4` and there'll be `2` below.

`>` duplicates the `4`, `/` is division turning it into a `1`. Then we push `02`. `&&&` joins the top four numbers of the stack in reverse order, giving `2012`. `#` outputs it. `????` just clears the stack because otherwise the top of the stack is output as well.

One point of interest is that the second `7` in `19977` was added because of Ropy. The `/` division in Ropy does `top / second` (opposite of the usual order in many stack-based languages), where `7 / 9` would give `0`. If we had a zero on top of the stack, Ropy would do some wild stuff with its direction of movement, so we need to push the other `7` to ensure that the top of the stack remains positive and Ropy keeps moving east.

### 2014: Fission

With its explicit entry points, this one is easy. `RDLU` create atoms (instruction pointers) in the corresponding direction, so the relevant bit is just this:

```
R"2014";

```

Note that there's a `U` in the source code as well, but that atom eventually hits one of the `*` from Wierd, which terminates the program (and this atom takes a lot longer than the `R` needs to print `2014`).

### 2015: Gol\>\<\>

Sp3000's more powerful \>\<\> derivative. It's largely backwards compatible with \>\<\> so the executed code is still:

```
v
\'\02'oo100@n590@n;

```

However, the rotation direction of `@` was changed, which is the standard trick to distinguish \>\<\> and Gol\>\<\> in polyglots, so this one prints `15` instead of `09`. Hence the weirdness in the second half of the program.

### 2016: CSL

CSL is quite interesting in that commands aren't executed immediately. Instead, each command is pushed onto a command-stack and `e` and `E` can be used to execute commands from it. The relevant code becomes:

```
v19977/2{@{{4{\_______>/02&&&#????        *    P+++++1P1P-1P+1E

```

So the `E` executes the entire command stack, which means that the stuff in front of it is executed in reverse. We only need to look up to the `*`:

```
1+P1-P1P1+++++P*

```

The `1`s push themselves onto the data stack. `+` and `-` are decrement/increment. `P` prints the top of the stack. Then `*` tries to multiply the top two values of the stack. However, the stack is empty, so this terminates the program.

---

At this point we get to languages which were released after this challenge was posted, so I'm not really counting them for the score, especially since I created these myself (not with this challenge in mind though). However, they do have some novel IP movement semantics, which made it easy to fit them into the polyglot while also adding something interesting to this showcase of 2D languages.

### 2017: Alice

Alice was designed to be a feature-rich Fungeoid. One interesting difference to the majority of (but not all) other 2D languages is that the IP can move either orthogonally, or diagonally. Switching between these also changes the semantics of almost all commands in the language. Furthermore, Alice supports both the traditional `<^>v` direction setters and `\/` mirrors, but mirrors have very unique behaviour in Alice (which makes it easy to lead the Alice IP to a so far unused portion of the code).

While most languages treat `\` and `/` as if they were mirrors at a 45° angle, and the IP as a light ray bouncing off of it, Alice treats them as having a 67.5° angle (which is closer to the angle of the actual slash glyphs), and the IP also moves *through* the mirror (hence the language's name). Due to this angle, mirrors switch between movement along orthogonal or diagonal directions. Furthermore, while in Ordinal mode (i.e. while the IP moves along diagonals), the grid doesn't wrap around and instead the IP bounces off the edges (whereas in Cardinal mode it does wrap around).

All in all, the code executed by Alice is the following:

```
v19
\ \

...

  >      "7102"4&o@

...

```

The IP starts in the top left corner as usual, `v` sends it south. Now the `\` reflects the IP to move northwest, where it immediately bounces off the left edge of the grid (and moves northeast instead). `1` can be ignored, the IP bounces off the top edge to move southeast next. We hit another `\` which reflects the IP north. `9` can also be ignored and then the IP wraps to the bottom of the grid. After a couple of lines we redirect it east with `>` for convenience. Then `"7102"` pushes the code points of the `2017`, `4&o` prints those four characters and `@` terminates the program.

### 2018: Wumpus

Wumpus is the first 2D language on a triangular grid, which makes movement through the code quite different (and again lets us reach an unused part of the code easily). So instead of thinking of each character in the grid as a little square, you should think of them as alternating upward and downward triangles. The top left corner is always an upward triangle.

Wumpus doesn't have direction setters like `<^>v`, but it does have mirrors `\/`. However, due to the triangular grid, these work differently from most other languages. The IP bounces off them like a light ray (as usual) but you should think of them as having an angle of 60° degrees. So an IP moving east will end up moving along the northwest axis of the grid.

As another difference to most other languages, the edges of the grid don't wrap, but the IP bounces off the edges instead (as if those edge cells contained the appropriate mirrors). Another fun little detail is that diagonals through the triangular grid actually look like staircases in the source code.

With that in mind, the code executed by Wumpus is the following (where I've replaced spaces with `.` for clarity:

```
v19977/
   02
  89
 ..
..
.....*...#2018O@

```

The `v19977` are just junk that we can ignore. `/` sends the IP northwest, where it moves through the `977` (from the right) again while bouncing off the top edge. Then the IP moves southwest through the `2089` and a bunch of spaces, before it hits the left edge to be reflected east again. `*` is also junk. Then finally `#2018` pushes `2018`, `O` prints it and `@` terminates the program.

---

### Missing years

Finally, some notes about years I haven't covered.

While researching 2D languages to find suitable ones across the years which could be used in a polyglot, I found out that contrary to popular belief, Befunge was *not* the first 2D language. That title seems to be held by Biota which was already created in 1991. Unfortunately, the language doesn't have any output, so I wasn't able to use it for this challenge.

As far as I can tell no 2D languages were created in 1992 and 1995. That leaves a few years I haven't covered:

* 1994: Orthagonal was created, independently of Befunge. The languages are semantically quite similar actually, but Orthagonal doesn't actually lay out the source code in 2D. Instead each line is an `(x, y, instruction)` tuple. I even obtained the language spec and original interpreter from the creator Jeff Epler, but in the end, the fact that the syntax isn't 2D made the language unsuitable for this polyglot.
* 1996: Orthogonal, a successor to Orthagonal (created by someone else) was created, but for the purposes of this polyglot suffers the same problems as Orthagonal.
* 1999: The only language I could find was Chris Pressey's cellular automaton REDGREEN. Unfortunately, as opposed to its predecessor RUBE, it doesn't seem to have any I/O semantics.
* 2000: There's another cellular automaton of Chris Pressey's called noit o' mnain worb but it also doesn't have any I/O. There's also Numberix which I haven't tried to get running and I'm not sure whether it would ignore non-hex characters in the source code.
* 2002: There's Clunk with no I/O and ZT whose language specification terrifies me.
* 2007: I found three languages here. Zetaplex is image based (so nope) and RubE On Conveyor Belts seems to require a header with a rather strict format which would have messed with the first line of the program. There's also Cellbrain by Quintopia, but it also seems to require a specific header.
* 2013: Again, I found three languages. Fishing might be possible with a good amount of restructuring but it would require the program to begin with a valid dock. Quipu, from memory, is way too strict about its syntax to allow much polyglotting. And Swordfish is another member of the \>\<\> family, but unfortunately I haven't been able to find an interpreter. Otherwise, this one would probably be fairly easy to add.

If anyone is interested, here is the complete list of implemented 2D languages sorted by years as far as I could find them (at the time this answer was posted). If any are missing from this list, please let me know in chat as I'd be really interested in a complete list.

# Answer
> 120 votes
## 15 years, Python

**Versions:** 0.9.1, 2.0.0, 2.2.0, 2.2.2, 2.5.0, 2.5.1, 3.0.0, 3.1.0, 3.1.3, 3.2.1, 3.3.0, 3.3.3, 3.4.0, 3.5.0 and 3.6.0a4. Versions not linked can be found on the downloads page.

The release date of 0.9.1 can be found here. Unfortunately I had to skip a large bunch of years due to missing old versions and compilation problems on my computer. The represented years are 1991, 2000-2002 and 2006-2016.

Tested on Arch Linux, using the gzipped versions.

```
# Note: This file needs a trailing newline due to 0.9.1

# 0.9.1: No bitwise operators
# This one errors out by division by zero.
try:
    eval('1&2')
except:
    print(1991)
    1/0

import sys

# 2.0.0: repr('\n') gives "'\012'" instead of "'\n'"
# == doesn't exist until Python 0.9.3 and <> doesn't exist in Python 3, hence we
# use <. Also, 0.9.1 doesn't have double quoted strings.
if repr('\n') < '\'\\n\'':
    print(2000)
    sys.exit()

# 2.2.0: email module still has a _Parser class - module revamped in 2.2.2
# I would use whether or not True exists as a name here, but weirdly "True"
# worked in 2.2.2 even though the docs say it was introduced in 2.3...
try:
    import email
    email._Parser
    print(2001)
    sys.exit()
except AttributeError:
    pass

# 2.2.2: a in b only works for strings a of length 1.
try:
    eval('"art" in "Martin"')
except TypeError:
    print(2002)
    sys.exit()

# 2.5.0: int() allows null bytes in integer to convert when given an explicit
# base.
try:
    print(int('2006\x00Hello, World!', 10))
    exit()
except ValueError:
    pass

# 2.5.1: pow overflows
# Note that we can't use ** here since that doesn't exist in 0.9.1.
if pow(2, 100) < 1:
    print(2007)
    exit()

# 3.0.0: round returns a float rather than an int.
if str(round(1, 0)) > '1':
    print(2008)
    exit()

# 3.1.0: bug caused complex formatting to sometimes drop the real part.
if format(complex(-0.0, 2.0), '-') < '(-':
    print(2009)
    exit()

# 3.1.3: str of a float is shorter than the repr of the same float.
if str(1.0/7) < repr(1.0/7):
    print(2010)
    exit()

# 3.2.1: For some weird reason, u'...' Unicode strings were disabled then
# re-enabled later.
try:
    eval('u"abc"')
except:
    print(2011)
    exit()

# 3.3.0: int still works without a first argument.
try:
    int(base=10)
    print(2012)
    exit()
except TypeError:
    pass

# 3.3.3: no enum module :(
try:
    import enum
except ImportError:
    print(2013)
    exit()

# 3.4.0: PEP 448 (additional unpacking generalisations) not implemented yet
try:
    eval('[*[1], *[2], *[3]]')
except SyntaxError:
    print(2014)
    exit()

# 3.5.0: No f-strings
try:
    eval('f"abc"')
except SyntaxError:
    print(2015)
    exit()

print(2016)

```

# Answer
> 55 votes
# Short and sweet; the three APLs (, J201, Dyalog 7.1) in 8 bytes

```
1993+1^2

```

1993 plus...

K: the first 1 integer {0} except {2}, i.e. {0}; 1993 – Try it online!

J: 1<sup>2</sup> = 1; 1994 – Try it online!

APL: LCM(1,2) = 2; 1995 – Try it online!

# Answer
> 47 votes
# 10 years, 12 languages, 2430 bytes

This answer is a collaboration between myself and user 1000000000.

A brief language list:

```
Brainfuck    1993
Befunge      1993
Piet         2001
Whitespace   2003
Braincopter  2005
Grass        2007
Starry       2008
Paintfuck    2008
Brainbool    2010 (11111011010)
Python 2.7.2 2011
Fission      2014
Brainflak    2016

```

Here is the code:

```
P3v="";print(sum([ord(x)for x in"~~~~~~~~~~~~~~~y"]));"""{}{}     + + +---[.     + +..  '.. +. +.. +. +. +.] + + + + + + +(((((()()()()){}){}){}){})({({} +-[<() + + + + + + +>-()])}{}<[. + + + + + + + +..-------  `             +.[-]]>)[< '
 17 12
# > 7*::,8 +:,,2 +,@<>R"2014";]*ne*e*es*s*swWWW*swWWWW*sw*e*e*e*eeev*wn*n*n*n*ne*e*se*s*s*s*sWWwWWWw**e*eeee*vwn*n*n*n*ne*e*se*s*s*s*sWWWw*eeee*e*ne*n*nWWWWWw*ne*nWWWWWWw*w*sw*se*sWWWWWWWw*s*WWWWWWwwwWWWWWWWWWWwWWWWWWWWWWwvwWWWwWWWWwvwWWwWWWwvwWWwWWWwvwWWwWWWwvwWWwwwwwwwwwwwWWWwWWWWWwWWWWWWWwWWWWWWWWWwWWWWWWWWWWWWWWWwWWWWWWWWWWWWwv `
255 0 255 255   0   192 192 0   192 192 0 192 192   192 255
255 192
255 255 192
255
255
0 255 255 0 255 255 0 255 255 0 255 255 0 192 192 192 255 255 255 255 255 0 192 192 0 0 255 255 255
255 0 0 255 0 192 192 0 192 192 0 192 192 192 255 255 192 255 255 192 255 255 192 255 255 0 255 255 0 255 255 0 255 255 0 192 192 255 255 255 255 255 255 255 255 255 255 255 255 0 192
192 0 0 255 0 192 192 0 192 192 0 192 192 0 192 192 192 255 255 192 255 255 192 255 255 0 255 255 0 255 255 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0
255 0 192 192 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 255 255 255
255 0 192 192 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 255 0 192
192 0 192 192 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 255 0 0
255 0 192 192 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 255 255 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 255 255 255
255 0 192 192 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 255 0 192
192 0 192 192 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 255 0 0
192 0 192 192 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 255 0 0 0 0 0 0 255 255
255 0 192 192 0 0 255 0 0 255 255 255 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 255 255 255 255 255 255 0 0 255 0 0 255 0 255 255 0 0 0 0 192 192 0 0
255 0 192 192 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 255 255 0 0 0 0 192 192 0 192 192
#   """

```

In order to fit this within a response I will forgo entire TIO links and will rather just post a link to a valid interpreter where the code may be input by the user. Here is a Pastebin link for that purpose.

## Piet

The PPM file format, one of the image formats that the Piet interpreter we used can read from, has a plaintext ASCII version. Using this we were able to embed the code of other languages as junk in the image file read by Piet and Braincopter.

The image looks like this:

Not all of the image is important for Piet. Here is a version with a line highlighting the path that Piet follows through the code:

Despite somewhat convoluted methods to create the program the program itself is quite simple. Along the top of the image it pushes `1 10 10 10 2` to the stack; along the side it multiplies thrice and adds once. In the bottom corner it outputs the result (2001) and then halts.

## Braincopter

Braincopter is the other visual language. It also relies on the same `ppm` image file to run. Because of very harsh restrictions in npiet our Braincopter code can only use a subset of the original Braincopter operations. We are restricted to using colors that are valid ops in Piet. This removes the `-` operator from Braincopter.

Here is the path traced out by the Braincopter code:

The Braincopter program is a bit strange because of the lack of a `-` operator. The walls of cyan and dark cyan serve to redirect the pointer but other than that it is identical to the following brainfuck:

```
++++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++..+++++.

```

This prints 2005.

## Paintfuck

Paintfuck is the third visual programming language on our list however instead of taking in a image and outputting text, Paintfuck takes in text and outputs an image.

Since Paintfuck ignores irrelevant characters as no-ops most of the code is unimportant. The relevant section of the code is:

```
nsn**ne*e*es*s*sw*sw*sw*e*e*e*eee*wn*n*n*n*ne*e*se*s*s*s*sww**e*eeee*wn*n*n*n*ne*e*se*s*s*s*sw*eeee*e*ne*n*nw*ne*nw*w*sw*se*sw*s*wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwnsn**ne*e*es*s*sw*sw*sw*e*e*e*eee*wn*n*n*n*ne*e*se*s*s*s*sww**e*eeee*wn*n*n*n*ne*e*se*s*s*s*sw*eeee*e*ne*n*nw*ne*nw*w*sw*se*sw*s*wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

```

While they are not no-ops the `w`s at the end of the code do nothing. They are there for the grass portion of the solution. `n`,`e`,`s`, and `w` are used to move around the image and `*` is used to plot a point at certain location. The program outputs:

A bigger version:

## Brainfuck

Like Paintfuck Brainfuck ignores most characters. Once again here are the important ones:

```
 []+++---[.++....+.+..+.+.+.]++++++++-[<+++++++>-]<[.++++++++..-------+.[-]]>[<>,+,,+,<>]

```

Most of this is further irrelevant by circumstance and just happen to be characters that some other language needed. The slimmer version of this code is:

```
+++++++[<+++++++>-]<[.++++++++..------.[-]]

```

This pretty simply prints `1993`.

## Brainbool

Brainbool is very similar to Brainfuck in its character selection. The big difference that allows the two to be woven together is the lack of a `-` in Brainbool. The important characters for Brainbool are:

```
[]+++[.++....+.+..+.+.+.]++++++++[<+++++++>]<[.++++++++..+.[]]>[<>,+,,+,<>]

```

Brainbool and brainfuck's outputs are mutually exclusive. Brainbool hides its output in the second set of `[]`. Brainfuck encounters `+++---` before it reaches the `[` setting it to zero and causing it to skip the output, while Brainbool only sees `+++` setting it to 1 causing it to pass through the loop. Similarly Brainbool is set to zero at the 4th loop causing it to skip while Brainfuck enters the loop with a value of 49.

Since Brainbool does not have decimal output it outputs the 2010 in binary:

```
11111011010

```

## Fission

The only part of the code that is important for fission is:

```
R"2014";

```

The `R` summons in a atom moving to the right, the `"2014"` prints `2014` and the `;` halts execution.

## Befunge

Befunge only passes through the following characters:

```
P3v
  7
  > 7*::,8 +:,,2 +,@

```

The `P3` are necessary to make a valid .ppm image for piet, and cumulatively push a 3 to the stack. the `v` is placed to redirect the the pointer downwards. It then passes through the `7` in the `17` used to indicate the width of the .ppm image. The `>` redirects the pointer to the right. `7*` multiplies the top of the stack by 7 leaving 49 (ASCII value of `1`) on the top of the stack. `::` duplicates the top of the stack twice. The `1` is output by `,`. `8 +` adds 8 to the top incrementing to ASCII `9`. `:,,` outputs `9` twice. `2 +` increments the ASCII `1` to an ASCII `3` and `,` prints. Finally `@` terminates the program.

All in all it prints `1993`.

## Whitespace

Whitespace, as the name might suggest, only uses whitespace in its programs. This is what the Whitespace interpreter sees:

```
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][LF]
[Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Tab][Tab][Tab][Tab][Tab][Space][Tab][Space][Space][Tab][Tab][LF]
[Tab][LF]
[Space][Tab][LF]
[LF]
[LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][Space][LF]
[Space][Space][Space][LF]

```

Most of what this code does is inconsequential to the execution of the program (all the lines containing only spaces simply push zero to the stack). The important part:

```
[Space][Space][Space][Tab][Tab][Tab][Tab][Tab][Space][Tab][Space][Space][Tab][Tab][LF]
[Tab][LF]
[Space][Tab][LF]
[LF]
[LF]

```

The first line pushes 2003 to the stack. After that `[Tab][LF][Space][Tab]` prints out the top of the stack (2003) as a number. Finally the last three linefeeds end the program execution.

## Grass

Grass ignores all character until the first `w` in the file and after that all characters that are not `w`, `W`, or `v`. The Grass interpreter reads:

```
wWWWwWWWWwv
wWWwWWWwv
wWWWwWWWWWwWWWWWWwwwWWWWWWWwWWWWWWwwwWWWWWWWWWWwWWWWWWWWWWwv
wWWWwWWWWwv
wWWwWWWwv
wWWwWWWwv
wWWwWWWwv
wWWwwwwwwwwwwwWWWwWWWWWwWWWWWWWwWWWWWWWWWwWWWWWWWWWWWWWWWwWWWWWWWWWWWWwv

```

The first line defines a function that adds two to whatever it is passed. The second line defines a function that adds four to whatever it is passed. The third defines a function that prints two plus the argument, the prints the argument twice, then finally prints seven plus the argument (Grass prints out characters based on ASCII value). The fourth, fifth and sixth lines define functions that add eight, add 16, add 32, and add 64 to their argument, respectively. The final line defines the main function which takes the character `w` (the only predefined number in Grass, ASCII value 119) and adds 185 to it using the add functions defined in the program as well as the built in add one function. Grass wraps numbers at 256 and so the result is 48 (corresponding to the character `0`). The function then passes this to the function of the third line which prints out 2007.

## Starry

Starry ignores everything except for space, `+`, `*`, `.`, `,`, ```, and `'`. Thus the starry interpreter sees only:

```
       + + +.     + +..  '.. +. +.. +. +. +. + + + + + + + + + + + + + + +. + + + + + + + +..  `             +. '
     *, +,, +,************************************************* `

```

However, the label and jump instructions are used to skip sections of the code which could cause problems if run, so the code is effectively this:

```
       + + +.     + +..  '  `             +. ' `

```

This code pushes two to the stack, duplicates it twice and then pops and prints one of them as a number. Then pushes zero, duplicates it and prints both zeros as numbers. Next it pops one of the twos and jumps and then pushes seven to the stack and pops and prints is as a number. Finally it pops the last two on the stack and jumps to the end of the program.

## Python 2.7.2

The Python code follows the format:

```
P3v="";print(sum([ord(x)for x in"~~~~~~~~~~~~~~~y"]));"""..."""

```

where `...` stands in for all of the other junk.

The first line, `P3v=""` is there because to be a valid `.ppm` file our code must start with `P3` this will normally error but if we tell python it is a variable declaration it will ignore it.

Next we have to print `2011`. However because of the way that a `.ppm` is formatted we cannot include any numbers in this line. In order to get around this we sum up all of the ASCII values of the string `"~~~~~~~~~~~~~~~y"` and print the result. Finally we use the triple quotes of a multiline comment so that python ignores everything else.

## Brainflak

We saved the best for last.

Brainflak, like others, ignores most characters. The relevant characters are:

```
(([()])){}{}[](((((()()()()){}){}){}){})({({}[<()>()])}{}<[[]]>)[<><>]

```

The python code, `(([()]))`, pushes -1 to the stack twice so it needs to be removed before the program begins processing.

After that Brainbool uses a `[]` nilad which does nothing and the program begins.

`(((((()()()()){}){}){}){})({({}[<()>()])}{}<[[]]>)` pushes 2016. The last `[<><>]` is remnants of Befunge and Brainfuck but luckily does nothing.

When the program terminates it prints the contents of the stack, that is it prints `2016`.

# Answer
> 38 votes
## 5 years

```
#define q/*-[>+<-----]>--.++++++++..------.[-][
print('2010'if len(bin.__doc__)==86else'2015')
"""*/
main(c){c=-4.5//**/
-4.5;printf("19%d",90-c);}
#define w/*]
*/"""

```

### 1989: C89<sup>\[1\]</sup>, and 1999: C99

The single line comment `//` was added in C99, so a C89 compiler would read that code as `c=-4.5 / /*comment*/ -4.5`, which is the same as `c=-4.5 / -4.5`, whereas a C99 compiler would read as `c=-4.5 //comment/**/`
`- 4.5`, which is the same as `c=-4.5 - 4.5`.
The Python part is a comment in the C program.

### 2010: Python 2.7, and 2015: Python 3.5

The docs vary between Python 3 and 2, this program uses the length of the docs to detect the Python version.
The C part is in a string in the Python program.

### 1993<sup>\[2\]</sup>: Brainfuck

It basically ignores everything that aren't `.,[]+-<>`. Since C program has a `,` in it, I had to make Brainfuck to dismiss that part by setting the current byte to 0.

---

1. The C89 spec was released in 1990. More info.
2. I couldn't find an official release date, so I'll believe Esolangs and Wikipedia.

# Answer
> 18 votes
## 15 years, JavaScript

Since JavaScript's release cycle is very unusual and inconsistent, I'm going to use the Firefox implementation. Please let me know if this is not allowed.

**Versions:** Phoenix 0.1, Firebird 0.6, Firefox 1.0.0, 1.5.0, 2.0.0, 3.0 Beta 1, 3.0.0, 3.5.0, 3.6.0, 4.0.0, 10.0.0, 18.0.0, 27.0.0, 35.0.0, 44.0.0 (all tested on Windows 7)

**Important note:** Installing and opening Firefox 1.0.0 or any later version **may erase all of your saved Firefox data**, including history and bookmarks.

Also, starting with 1.0.0, you can only have one version open at a time; trying to open another version results in a new window of the already-open version.

### Instructions

### Code

```
<script onbeforeunload="123">
// This uses document.write because alert does nothing in Phoenix (Firefox) 0.1.
document.write((function () {
    function assert (code) {
        try {
            eval(code);
            return true;
        } catch (e) {
            return false;
        }
    }

    // Firefox 44 supports octal and binary literals in Number(); Firefox 35 does not.
    if (Number("0o1") === 1)
        return 2016;

    // Firefox 35 supports template strings; Firefox 27 does not.
    if (assert("`abc`"))
        return 2015;

    // Firefox 27 supports argument spreading; Firefox 18 does not.
    if (assert("Math.max(...[1, 2, 3])"))
        return 2014;

    // Firefox 18 supports default arguments; Firefox 10 does not.
    if (assert("function q(a = 1) { }"))
        return 2013;

    // Firefox 10 has basic WeakMap support; Firefox 4 does not.
    if (assert("WeakMap.a"))
        return 2012;

    // Firefox 4 has basic typed array support; Firefox 3.6 does not.
    if (assert("Int8Array.a"))
        return 2011;

    // Firefox 3.6 added the async attribute to script elements.
    if (assert("document.getElementsByTagName('script')[0].async.a"))
        return 2010;

    // Firefox 3.5 added the String.prototype.trim() method.
    if (assert("'abc'.trim()"))
        return 2009;

    // Firefox 3.0 added partial support for object destructuring.
    if (assert("var {c} = {c: 7}"))
        return 2008;

    // Firefox 3.0 beta 1 added the Array.prototype.reduce() and Array.prototype.reduceRight() methods.
    if (assert("[].reduce.a"))
        return 2007;

    // Firefox 2.0 added support for restricted words as properties.
    if (assert("({if:1}).if"))
        return 2006;

    // Firefox 1.5 added the Array.prototype.indexOf() methods, along with a couple other Array methods.
    if (assert("[1].indexOf(1)"))
        return 2005;

    // Practically the only JS difference between v0.6 and v1.0 is the addition of the onbeforeunload event.
    if (assert("document.getElementsByTagName('script')[0].onbeforeunload.a"))
        return 2004;

    // The Object.prototype.eval() method was removed in Firebird 0.6.
    if (!assert("'abc'.eval()"))
        return 2003;

    // We're all the way back to the good old Phoenix 0.1 browser...
    return 2002;
})());
</script>

```

# Answer
> 13 votes
# 3 years (GolfScript, CJam, MATL), ~~24~~ 23 bytes

```
[A11]Wd%;200 1e2/0 8_+(

```

This outputs

* `2007` in GolfScript.
* `2015` in CJam (version 0.6.5).
* `2016` in MATL (version 19.2.0).

## Explanation

### Golfscript

Undefined tokens are noops in GolfScript. The only parts of the code that actually do something are:

```
200      Push 200
           STACK: 200
1        Push 1
            STACK: 200, 1
/        Divide
           STACK: 200
0        Push 0
           STACK: 200, 0
8        Push 8
           STACK: 200, 0, 8
+        Add
           STACK: 200, 8
(        Subtract 1
           STACK: 200, 7
         Implicitly display 200, 7 as "2007"

```

### CJam

```
[A11]    Push array [10 11]
           STACK: [10 11]
W        Push -1
           STACK: [10 11], -1
d        Convert to double
           STACK: [10 11], -1.0
%        Select elements from array
           STACK: [11 10]
;        Pop
           STACK is empty
200      Push 200
           STACK: 200
1e2      Push 100
           STACK: 100
/        Divide
           STACK: 2
0        Push 0
           STACK: 2, 0
8_       Push 8 and duplicate
           STACK: 2, 0, 8, 8
+        Add
           STACK: 2, 0, 16
(        Subtract 1
           STACK: 2, 0, 15
         Implicitly display 2, 0, 15 as "2015"

```

### MATL

Everything from `%` onwards is a comment.

```
[A11]    Push array [5 11]
           STACK: [5 11]
W        2 raised to that
           STACK: [32 2048]
d        Compute increment
           STACK: 2016
         Implicitly display as "2016"

```

# Answer
> 13 votes
# 6 languages, Turtlèd and brainfuck, Python 3.5, Python 2.7, \>\<\>, Fission

Turtlèd has not existed before this year, and so easily objective, even if the github commits don't count, and BF has the esolang page evidence, released 1993. Python 3.5 is 2015, 2.7 is 2010. \>\<\> also has esolang page, stating 2009, as does Fission, 2014

```
#-[>+<-----]>--.++++++++..------#"2016"/
print(2015 if len(len.__doc__)==42 else 2010)
#;                           oooo"2009"/
#;"4102"L

```

I should probably give credit to the bf constants page on esolangs... ¯\\\_(ツ)\_/¯

## How it works, kind of:

### Turtlèd:

Turtlèd doesn't really do anything for lines other than the first:

```
#-[>+<-----]>--.++++++++..------#"2016"/
  ^sets string variable to this   ^ prints 2016

```

/ is a nop

### Brainfuck

Brainfuck ignores chars not in its commands

it sees `-[>+<-----]>--.++++++++..------.` (the last . is from the python part)

which just does Brainfuck stuff, it uses wrapping to divide 255 by 5, then subtract 2 from the result, print, increment 8 times, print twice, decrement 6 times, print

### Python 2 and 3

```
print(2015 if len(len.__doc__)==42 else 2010)

```

the length of the docs for len vary between the versions, so it prints the year for version 3 if it is the right length, else for version 2.

### \>\<\>

\# reflects the pointer backwards, so it hits the / on the other side of that line, passes through the space between `else` and `2010`, then reflects again to hit "2009", pushing 9,0,0,2 onto stack, then printing out reversed.

### Fission

Fission has spawners, so we can have a line at the bottom that it executes alone:

```
#;"4102"L
        L spawn left moving atom
  "4102"  print this right to left
 ;        halt
# python comment

```

# Answer
> 13 votes
## 3 years, 3 languages: C, TeX, MIXAL

```
*main(){puts("1990");}/*\newwrite\O\openout\O=O\write\O{1982}\bye
START   ENTA    1997
        CHAR
        STX     6
        OUT     6(19)
        HLT
        END     START   */

```

Name the file `date.mixal`.

1. C (1990) -- Compiles with warnings and prints `1990` to `stdout`.
2. TeX (1982) -- Compile with `tex date.mixal`; prints `1982` to the file `O.tex` (ignore the DVI output).
3. MIXAL (1997) -- Compile using GNU Mix Development Kit, `mixasm date.mixal` and run with `mixvm -r date.mix`; prints `1997` to the teletype device (=`stdout`).

The TeX and MIXAL programs are in a comment in the C program; the MIXAL program comes after `\bye` so TeX ignores it. The C and TeX programs are a comment in the MIXAL program. For some reason `gcc` is willing to accept `*main`.

# Answer
> 12 votes
# 2 languages, Python 2.7 and Python 3.5

Python 2.7 was released in 2010.

Python 3.5 was released in 2015.

```
print('2010'if 3/2==1else'2015')

```

This relies on PEP 238 where the operator `/` was changed from integer division in Python 2 to floating-point division in Python 3.

# Answer
> 12 votes
# 8 years, TI-Basic

```
Disp 1996           <-- TI-83
Text(-1,1,1,1
ClrHome
Disp 1999           <-- TI-83+ OS 1.03 (initial OS)
sub(1
ClrHome
Disp 2002           <-- TI-83+ OS 1.15
isClockOn
ClrHome
Disp 2004           <-- TI-84+ OS 2.21
invT(e,1
ClrHome
Disp 2005           <-- TI-84+ OS 2.40
CLASSIC
ClrHome
Disp 2009           <-- TI-84+ OS 2.53
BackgroundOn
ClrHome
Disp 2013           <-- TI-84+ Color Silver Edition
Send({1
ClrHome
2015                <-- TI-84+ Color Edition OS 5.1

```

"Any of the programs may print to STDERR, or throw runtime/compile time errors and warnings as long as the correct output is still printed to STDOUT or a file." Currently, the only non-error display is the year, so we are complying with this rule. However, if you'd like to write to the memory instead, replace `Disp (date)` with `(date)->I`.

References:

1. Calculator release dates - https://epsstore.ti.com/OA\_HTML/csksxvm.jsp?nSetId=74258
2. TI-83+ OS 1.15 release date - http://wikiti.brandonw.net/index.php?title=83Plus:OS:VersionDifferences#TIOS\_1.15
3. Calculator compatibility - http://tibasicdev.wikidot.com/compatibility
4. TI-84+CSE release date - https://www.amazon.com/Texas-Instruments-Silver-Graphing-Calculator/dp/B00AWRQKDC
5. TI-84+CE release date - http://www.prnewswire.com/news-releases/texas-instruments-unveils-the-new-ti-84-plus-ce-300026266.html and https://www.cemetech.net/forum/viewtopic.php?t=8870

# Answer
> 9 votes
# 5 years, Go 1.0, 1.1, 1.4, 1.5, 1.6: ~~285~~ 257 bytes

(1.2 was released in 2013 like 1.1, 1.3 in 2014 like 1.4, and 1.7 in 2016 like 1.6.)

Have not tested this out on every version because I can access only 1.6, but it should work in theory! Language changes would likely have caused the program not to compile, so I relied on standard library changes.

```
package main
import(."fmt"
."reflect"
."time")
func main(){s:="6"
if _,e:=Parse("2016-Sep-30","2016-Sep-31");e==nil{s="5"}
if Sprint(ValueOf(0))!="0"{s="4"}
if Sprint(&map[int]int{1:1})[0]!='&'{s="3"}
if string(0xd800)==string(0xfffd){s="2"}
Print("201"+s)}

```

Ungolfed and commented:

```
package main

import (
    "fmt"
    "reflect"
    "time"
)   package main

import (
    . "fmt"
    . "reflect"
    . "time"
)

func main() {
    s := "6"
    // 1.6: time.Parse rejects invalid days
    if _, e := Parse("2016-Sep-30", "2016-Sep-31"); e == nil {
        s = "5"
    }
    // 1.5: A reflect.Value now prints what it holds, rather than use
    // its String() method
    if Sprint(ValueOf(0)) != "0" {
        s = "4"
    }
    // 1.4: Printing pointers to maps gives the map instead of the address
    if Sprint(&map[int]int{1: 1})[0] != '&' {
        s = "3"
    }
    // 1.1: Unicode surrogate halves are no longer allowed
    if string(0xd800) == string(0xfffd) {
        s = "2"
    }
    Print("201" + s)
}

```

# Answer
> 8 votes
# 7 years, 8 browsers

Not exactly language release dates because css doesn't actually have releases, but browser versions (could be thought as compiler versions maybe?)

For the following browsers, this prints the browser name, version and release date and nothing else. It does print the same thing for a few later versions, (you will see chromium is one version late in the screenshots because it's hard to download old versions of chrome by version number)

I could print the version number I used but I preferred to show the first version where the used feature is introduced.

* IE6
* IE7
* IE8
* IE9 (untested, don't have an IE9 around)
* Firefox 4
* Firefox 3.6
* Chrome 18
* Chrome 21
* Modern Browsers

## index.html

```
<!DOCTYPE html>
 <html>
  <head>
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <link rel=stylesheet href=style.css>
  </head>
  <body>
    <div class=borderbox>
      <div class="inlineblock">
         IE6-2001
      </div>

      <div class="white">
        <div class="outofbox">
          <a href="#">IE8-2009</a>
        </div>
        <div class="inherit">
          <a href="#">IE7-2006</a>
        </div>
      </div>
    </div>
    <div class="white">
      <header class="filter-quirk filter-blur filter-blur-url">
        IE9
      </header>
    </div>
    <div class="flex white">
      Modern Browsers - 2017
    </div>
    <div class="webkit-flex">
      <div class="">
        Chrome 21-2012
      </div>
    </div>
    <div class="webkit-invert white flexdisable">
      <div class="">
        Chrome 18-2012
      </div>
    </div>

    <svg style="position: absolute; top: -99999px" xmlns="http://www.w3.org/2000/svg">

    </svg>

    <div class="filter">
      <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
        <g
           transform="scale(8)"
           aria-label="FF4"
           id="text8419">
           <rect
              style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.79374999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
              id="rect21965"
              width="17.005648"
              height="3.9855044"
              x="-0.16825682"
              y="-0.025296567" />
          <path
             d="m 1.0052634,1.5511362 v 0.7639843 h 0.4564063 q 0.092604,0 0.092604,0.066146 0,0.069453 -0.092604,0.069453 H 0.69107072 q -0.089297,0 -0.089297,-0.069453 0,-0.066146 0.089297,-0.066146 h 0.1785938 V 0.72431329 h -0.1785938 q -0.089297,0 -0.089297,-0.069453 0,-0.066146 0.089297,-0.066146 H 2.1793519 V 1.0484278 q 0,0.089297 -0.069453,0.089297 -0.066146,0 -0.066146,-0.089297 V 0.72431329 H 1.0052634 V 1.4155373 H 1.4848207 V 1.2667091 q 0,-0.089297 0.066146,-0.089297 0.069453,0 0.069453,0.089297 v 0.4332552 q 0,0.089297 -0.069453,0.089297 -0.066146,0 -0.066146,-0.089297 V 1.5511362 Z"
             style="fill:#000000;stroke-width:0.79374999"
             id="path8421" />
          <path
             d="m 2.9883464,1.5511362 v 0.7639843 h 0.4564063 q 0.092604,0 0.092604,0.066146 0,0.069453 -0.092604,0.069453 h -0.770599 q -0.089297,0 -0.089297,-0.069453 0,-0.066146 0.089297,-0.066146 H 2.8527475 V 0.72431329 H 2.6741537 q -0.089297,0 -0.089297,-0.069453 0,-0.066146 0.089297,-0.066146 H 4.1624349 V 1.0484278 q 0,0.089297 -0.069453,0.089297 -0.066146,0 -0.066146,-0.089297 V 0.72431329 H 2.9883464 V 1.4155373 H 3.4679037 V 1.2667091 q 0,-0.089297 0.066146,-0.089297 0.069453,0 0.069453,0.089297 v 0.4332552 q 0,0.089297 -0.069453,0.089297 -0.066146,0 -0.066146,-0.089297 V 1.5511362 Z"
             style="fill:#000000;stroke-width:0.79374999"
             id="path8423" />
          <path
             d="M 5.6692683,1.8917872 H 4.7729923 V 1.7363445 l 0.754062,-1.28322911 h 0.277813 V 1.7561883 h 0.112448 q 0.0893,0 0.0893,0.069453 0,0.066146 -0.0893,0.066146 h -0.112448 v 0.4233333 h 0.112448 q 0.0893,0 0.0893,0.066146 0,0.069453 -0.0893,0.069453 h -0.499402 q -0.0893,0 -0.0893,-0.069453 0,-0.066146 0.0893,-0.066146 h 0.251355 z m 0,-0.1355989 V 0.58871439 h -0.07938 L 4.9019713,1.7561883 Z"
             style="fill:#000000;stroke-width:0.79374999"
             id="path8425" />
          <path
             d="M 8.2881171,1.6077068 H 6.9585859 q -0.089297,0 -0.089297,-0.069453 0,-0.066146 0.089297,-0.066146 h 1.3295312 q 0.089297,0 0.089297,0.066146 0,0.069453 -0.089297,0.069453 z"
             style="stroke-width:0.79374999"
             id="path8422" />
          <path
             d="m 8.9582054,0.90656104 q 0,-0.14882812 0.1785937,-0.31749999 0.1819011,-0.17197916 0.4365625,-0.17197916 0.2414323,0 0.4233333,0.17197916 0.1852081,0.17197916 0.1852081,0.39687498 0,0.14882817 -0.0893,0.28111977 Q 10.006617,1.3960402 9.7056533,1.67716 L 9.0210439,2.3154672 v 0.00992 H 10.059533 V 2.2063266 q 0,-0.089297 0.06945,-0.089297 0.06614,0 0.06614,0.089297 V 2.460988 H 8.8920596 V 2.2625506 L 9.6725804,1.5283318 q 0.2315104,-0.2282031 0.3009635,-0.3307291 0.07276,-0.102526 0.07276,-0.21497396 0,-0.17197916 -0.1422132,-0.30096353 -0.1422136,-0.12898437 -0.3307292,-0.12898437 -0.1686718,0 -0.3075781,0.0992188 -0.1355989,0.0992188 -0.1752864,0.24804686 -0.019844,0.0661458 -0.069453,0.0661458 -0.023151,0 -0.042995,-0.0165365 -0.019844,-0.0198437 -0.019844,-0.0429948 z"
             style="stroke-width:0.79374999"
             id="path8424" />
          <path
             d="m 12.207981,1.3001287 v 0.3307292 q 0,0.3902604 -0.171979,0.6349999 -0.171979,0.2447396 -0.446484,0.2447396 -0.274506,0 -0.446485,-0.2447396 Q 10.971054,2.0211183 10.971054,1.6308579 V 1.3001287 q 0,-0.39356766 0.171979,-0.63830724 0.171979,-0.24473957 0.446485,-0.24473957 0.274505,0 0.446484,0.24473957 0.171979,0.24473958 0.171979,0.63830724 z M 11.589518,0.55268084 q -0.224896,0 -0.353881,0.22820312 -0.128984,0.22489584 -0.128984,0.53578124 v 0.2943489 q 0,0.3241146 0.132292,0.5457031 0.135599,0.2182813 0.350573,0.2182813 0.224895,0 0.35388,-0.2248959 0.128984,-0.2282031 0.128984,-0.5390885 V 1.3166652 q 0,-0.32411458 -0.135599,-0.54239582 -0.132292,-0.22158854 -0.347265,-0.22158854 z"
             style="stroke-width:0.79374999"
             id="path8426" />
          <path
             d="M 13.642054,0.43692564 V 2.3253891 h 0.459713 q 0.0893,0 0.0893,0.066146 0,0.069453 -0.0893,0.069453 h -1.055026 q -0.0926,0 -0.0926,-0.069453 0,-0.066146 0.0926,-0.066146 h 0.459714 V 0.61551938 l -0.373724,0.37372394 q -0.02646,0.0264584 -0.06945,0.0264584 -0.02646,0 -0.0463,-0.0198438 -0.01654,-0.023151 -0.01654,-0.056224 0,-0.0297656 0.03638,-0.0661458 l 0.436562,-0.43656248 z"
             style="stroke-width:0.79374999"
             id="path8428" />
          <path
             d="M 15.625137,0.43692564 V 2.3253891 h 0.459713 q 0.0893,0 0.0893,0.066146 0,0.069453 -0.0893,0.069453 h -1.055026 q -0.0926,0 -0.0926,-0.069453 0,-0.066146 0.0926,-0.066146 h 0.459714 V 0.61551938 l -0.373724,0.37372394 q -0.02646,0.0264584 -0.06945,0.0264584 -0.02646,0 -0.0463,-0.0198438 -0.01654,-0.023151 -0.01654,-0.056224 0,-0.0297656 0.03638,-0.0661458 l 0.436563,-0.43656248 z"
             style="stroke-width:0.79374999"
               id="path8430" />
          </g>
      </svg>
    </div>
    <div class="white gradient msfilter" style=color:white>
      FF3.6-2010
    </div>
  </body>
 </html>

```

## style.css

```
.borderbox {
    height: 40px;
    overflow: hidden;
    padding-bottom: 100px;
}
.outofbox {
    background: blue none repeat scroll 0 0;
    margin-top: 20px;
    opacity: 0;
}
.white {
    color: white;
}
.outofbox a, .inherit a, .inherit a:visited, .outofbox a:visited {
    color: inherit;
}
.inlineblock {
    display: inline;
    width: 100%;
    zoom: 1;
    display: inline-block;
    margin-left: 100px;
    text-align: right;
}
.white header{
  color: black;
}
.absolute{
  position: absolute;
}
.flex{
  display: none;
  display: flex;
}
.flex.white{
  filter: invert(100%)
}
.webkit-flex{
  display: none;
  display: -webkit-flex;
  overflow: hidden;
  flex-flow: column;
  height: 3em;
  justify-content: flex-end;
}
.webkit-flex div{
  margin-bottom: -1.1em;
}
.flexdisable{
  display: -webkit-flex;
  overflow: hidden;
  -webkit-flex-flow: column;
  -webkit-justify-content: flex-end;
  height: 60px;
}
.flexdisable div{
  margin-bottom: -30px;
}
.filter-quirk{
  filter: url(#quirk);
}
.filter-blur{
  filter: blur(100px);
  -webkit-filter: blur(100px);
}
.webkit-blur{
  -webkit-filter: blur(100px);
}
.webkit-invert{
  -webkit-filter: invert(100%);
  filter: none;
}
.filter-url-dark{
  -webkit-filter: url(filter.svg#Invert);
  filter: url(filter.svg#Invert) invert(100%);
}
.filter-blur-url{
  filter: url(filter.svg#blur) url(filter.svg#brightness);
}
.filter{
  filter: invert(100%) brightness(100%);
  -webkit-filter: invert(100%) brightness(100%) blur(100px);
}
.filter svg{
  position: absolute;
}
.filter svg rect{
  filter: invert(100%);
  -webkit-filter: invert(100%);
}
.msfilter{
    /* IE 8 */
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
  /* IE 5-7 */
  filter: alpha(opacity=0);
}
.opacity{

}
.black{
  background: black;
}
.gradient{
  width: 100px;
  background: -moz-linear-gradient( 45deg, #000, #000 );
  font-weight: bold;
}

```

## filter.svg

```
    <!DOCTYPE html>
 <html>
  <head>
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <link rel=stylesheet href=style.css>
  </head>
  <body>
    <div class=borderbox>
      <div class="inlineblock">
         IE6-2001
      </div>

      <div class="white">
        <div class="outofbox">
          <a href="#">IE8-2009</a>
        </div>
        <div class="inherit">
          <a href="#">IE7-2006</a>
        </div>
      </div>
    </div>
    <div class="white">
      <header class="filter-quirk filter-blur filter-blur-url">
        IE9
      </header>
    </div>
    <div class="flex white">
      Modern Browsers - 2017
    </div>
    <div class="webkit-flex">
      <div class="">
        Chrome 21-2012
      </div>
    </div>
    <div class="webkit-invert white flexdisable">
      <div class="">
        Chrome 18-2012
      </div>
    </div>

    <svg style="position: absolute; top: -99999px" xmlns="http://www.w3.org/2000/svg">

    </svg>

    <div class="filter">
      <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
        <g
           transform="scale(8)"
           aria-label="FF4"
           id="text8419">
           <rect
              style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.79374999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
              id="rect21965"
              width="17.005648"
              height="3.9855044"
              x="-0.16825682"
              y="-0.025296567" />
          <path
             d="m 1.0052634,1.5511362 v 0.7639843 h 0.4564063 q 0.092604,0 0.092604,0.066146 0,0.069453 -0.092604,0.069453 H 0.69107072 q -0.089297,0 -0.089297,-0.069453 0,-0.066146 0.089297,-0.066146 h 0.1785938 V 0.72431329 h -0.1785938 q -0.089297,0 -0.089297,-0.069453 0,-0.066146 0.089297,-0.066146 H 2.1793519 V 1.0484278 q 0,0.089297 -0.069453,0.089297 -0.066146,0 -0.066146,-0.089297 V 0.72431329 H 1.0052634 V 1.4155373 H 1.4848207 V 1.2667091 q 0,-0.089297 0.066146,-0.089297 0.069453,0 0.069453,0.089297 v 0.4332552 q 0,0.089297 -0.069453,0.089297 -0.066146,0 -0.066146,-0.089297 V 1.5511362 Z"
             style="fill:#000000;stroke-width:0.79374999"
             id="path8421" />
          <path
             d="m 2.9883464,1.5511362 v 0.7639843 h 0.4564063 q 0.092604,0 0.092604,0.066146 0,0.069453 -0.092604,0.069453 h -0.770599 q -0.089297,0 -0.089297,-0.069453 0,-0.066146 0.089297,-0.066146 H 2.8527475 V 0.72431329 H 2.6741537 q -0.089297,0 -0.089297,-0.069453 0,-0.066146 0.089297,-0.066146 H 4.1624349 V 1.0484278 q 0,0.089297 -0.069453,0.089297 -0.066146,0 -0.066146,-0.089297 V 0.72431329 H 2.9883464 V 1.4155373 H 3.4679037 V 1.2667091 q 0,-0.089297 0.066146,-0.089297 0.069453,0 0.069453,0.089297 v 0.4332552 q 0,0.089297 -0.069453,0.089297 -0.066146,0 -0.066146,-0.089297 V 1.5511362 Z"
             style="fill:#000000;stroke-width:0.79374999"
             id="path8423" />
          <path
             d="M 5.6692683,1.8917872 H 4.7729923 V 1.7363445 l 0.754062,-1.28322911 h 0.277813 V 1.7561883 h 0.112448 q 0.0893,0 0.0893,0.069453 0,0.066146 -0.0893,0.066146 h -0.112448 v 0.4233333 h 0.112448 q 0.0893,0 0.0893,0.066146 0,0.069453 -0.0893,0.069453 h -0.499402 q -0.0893,0 -0.0893,-0.069453 0,-0.066146 0.0893,-0.066146 h 0.251355 z m 0,-0.1355989 V 0.58871439 h -0.07938 L 4.9019713,1.7561883 Z"
             style="fill:#000000;stroke-width:0.79374999"
             id="path8425" />
          <path
             d="M 8.2881171,1.6077068 H 6.9585859 q -0.089297,0 -0.089297,-0.069453 0,-0.066146 0.089297,-0.066146 h 1.3295312 q 0.089297,0 0.089297,0.066146 0,0.069453 -0.089297,0.069453 z"
             style="stroke-width:0.79374999"
             id="path8422" />
          <path
             d="m 8.9582054,0.90656104 q 0,-0.14882812 0.1785937,-0.31749999 0.1819011,-0.17197916 0.4365625,-0.17197916 0.2414323,0 0.4233333,0.17197916 0.1852081,0.17197916 0.1852081,0.39687498 0,0.14882817 -0.0893,0.28111977 Q 10.006617,1.3960402 9.7056533,1.67716 L 9.0210439,2.3154672 v 0.00992 H 10.059533 V 2.2063266 q 0,-0.089297 0.06945,-0.089297 0.06614,0 0.06614,0.089297 V 2.460988 H 8.8920596 V 2.2625506 L 9.6725804,1.5283318 q 0.2315104,-0.2282031 0.3009635,-0.3307291 0.07276,-0.102526 0.07276,-0.21497396 0,-0.17197916 -0.1422132,-0.30096353 -0.1422136,-0.12898437 -0.3307292,-0.12898437 -0.1686718,0 -0.3075781,0.0992188 -0.1355989,0.0992188 -0.1752864,0.24804686 -0.019844,0.0661458 -0.069453,0.0661458 -0.023151,0 -0.042995,-0.0165365 -0.019844,-0.0198437 -0.019844,-0.0429948 z"
             style="stroke-width:0.79374999"
             id="path8424" />
          <path
             d="m 12.207981,1.3001287 v 0.3307292 q 0,0.3902604 -0.171979,0.6349999 -0.171979,0.2447396 -0.446484,0.2447396 -0.274506,0 -0.446485,-0.2447396 Q 10.971054,2.0211183 10.971054,1.6308579 V 1.3001287 q 0,-0.39356766 0.171979,-0.63830724 0.171979,-0.24473957 0.446485,-0.24473957 0.274505,0 0.446484,0.24473957 0.171979,0.24473958 0.171979,0.63830724 z M 11.589518,0.55268084 q -0.224896,0 -0.353881,0.22820312 -0.128984,0.22489584 -0.128984,0.53578124 v 0.2943489 q 0,0.3241146 0.132292,0.5457031 0.135599,0.2182813 0.350573,0.2182813 0.224895,0 0.35388,-0.2248959 0.128984,-0.2282031 0.128984,-0.5390885 V 1.3166652 q 0,-0.32411458 -0.135599,-0.54239582 -0.132292,-0.22158854 -0.347265,-0.22158854 z"
             style="stroke-width:0.79374999"
             id="path8426" />
          <path
             d="M 13.642054,0.43692564 V 2.3253891 h 0.459713 q 0.0893,0 0.0893,0.066146 0,0.069453 -0.0893,0.069453 h -1.055026 q -0.0926,0 -0.0926,-0.069453 0,-0.066146 0.0926,-0.066146 h 0.459714 V 0.61551938 l -0.373724,0.37372394 q -0.02646,0.0264584 -0.06945,0.0264584 -0.02646,0 -0.0463,-0.0198438 -0.01654,-0.023151 -0.01654,-0.056224 0,-0.0297656 0.03638,-0.0661458 l 0.436562,-0.43656248 z"
             style="stroke-width:0.79374999"
             id="path8428" />
          <path
             d="M 15.625137,0.43692564 V 2.3253891 h 0.459713 q 0.0893,0 0.0893,0.066146 0,0.069453 -0.0893,0.069453 h -1.055026 q -0.0926,0 -0.0926,-0.069453 0,-0.066146 0.0926,-0.066146 h 0.459714 V 0.61551938 l -0.373724,0.37372394 q -0.02646,0.0264584 -0.06945,0.0264584 -0.02646,0 -0.0463,-0.0198438 -0.01654,-0.023151 -0.01654,-0.056224 0,-0.0297656 0.03638,-0.0661458 l 0.436563,-0.43656248 z"
             style="stroke-width:0.79374999"
               id="path8430" />
          </g>
      </svg>
    </div>
    <div class="white gradient msfilter" style=color:white>
      FF3.6-2010
    </div>
  </body>
 </html>

```

# Answer
> 7 votes
# 4 years, 99 bytes/77 chars

```
v=1//1;"""
 1991/*"""
for i in[0]:print 2010#➕➕
"""
"
>9002nnnn;
"""#*/

```

*Note: I'm not sure if the years are correct*

* Python 2.7, 2010
* Javascript, 1991
* Emotinomicon, 2015
* `><>`, 2009

It took me a while to figure out how to make Python and JS work together.

# Explanation

`v=1//1;"""` sets variable `v` to `1` divided by `1` in Python, and to `1` in Javascript (`//` starts a comment in Javascript), and `;"""` starts a multiline string in Python. The `;` can't be replaced with a newline because that would make Javascript stop working.

`1991/*"""` is the rest of the multiline string. The space is needed so that \>\<\> doesn't push `1` to the stack. Since the start of the multiline string was part of a comment in Javascript, it prints `1991` and starts a multiline comment.

`for i in[0]:print 2010#➕➕` in Python, is a for loop that iterates the list `[0]` and runs `print 2010`. The comment is just the Emotinomicon code (it ignores everything that isn't an emoji or a string). In \>\<\>, it (`f`) pushes `15` to the stack.

The for loop can't be removed because since \>\<\>'s IP is going down in column 1, and `p` isn't a valid command in \>\<\>. You also can't replace it by an `if` statement, because `i` is the command to take input in \>\<\>.

`"""` is the start of a multiline string.

`"` is part of the multiline string, needed to close the string we opened in \>\<\> (the first quotation mark of the previous line started a string in \>\<\>).

`>9002nnnn;` in \>\<\>, changes IP direction to right, pushes `9`, `0`, `0` and `2`, output these as numbers and ends the program.

`"""#*/` in Python, ends the multiline string and starts a comment. In Javascript, `*/` makes the multiline comment end.

---

Bonus version with Gol\>\<\>:

### 5 languages, 4 years, ~~118~~ 114 bytes/~~96~~ 92 chars

```
v=1//1;"""
 1991/*"""
for i in[0]:print 2010#➕➕
"""
`
"
>9002nnnn;
"
>5102nnnn;
"""#*/

```
* Golfish v0.4.2, 2015

# Explanation²

IP starts at the upper left corner, going right. The `v` makes it go down.

`f` pushes `15`.

`"` starts string.

``` is used to escape characters, something that \>\<\> doesn't have.

`"` should close the string, but we used ```, so it won't.

`>` part of the string.

`"` ends the string.

`>5102nnnn;` is the actual code. `>` makes the IP go right, `5102` pushes `5`, `1`, `0` and `2`, and `nnnn;` prints the numbers and ends the program.

# Answer
> 6 votes
## 3 years, 89 bytes

### Python 2, JavaScript (ES6) and Perl

```
eval((["1","print=_=>console.log(1995)"])[+(2/3>0)]);print(eval(("1991",1987)["$$">"0"]))

```

The first `eval` will run `1` on Python 2 and `print=_=>console.log(1995)` on JavaScript and Perl using the integer division feature of Python 2. This creates a `print` function in JavaScript and Perl only silently cares about the syntax errors and carries on regardless.

The second `eval` relies on Perl interpolating the variable `$$` (current PID) into the string, which will be true when compared (using the `>` operator) against `"0"` (Python requires a string in that comparison whereas Perl implicitly converts to integer).

I could have shoe-horned in more languages, but wanted to have a solution that didn't abuse comments and only worked in 'regular' languages.

I used this Wikipedia page to retrieve the years to use.

# Answer
> 2 votes
# 3 languages, 3 years

An ad-hoc answer for fun.

```
2002!~+++++++[<+++++++>-]<[.++++++++..------.[-]] 2016 !.

```
* **Mouse-2002**: everything after `~` is a comment, and the first part, which could also be written `C0U!!!`, prints `2002`.
* **this pre-challenge commit of Calc**: which is a stack-based calculator interpreter I *just* designed in C11 for Programming II, the part of the program before the first space prints an error (allowed under the challenge spec), and `2016 !.` prints `2016`.
* **Brainfuck**: prints 1993 as seen in other answers. The final extraneous `.` is ignored by `beef`.

Note that Calc's display of the current stack `< stack` with every non-empty input line is part of the prompt `>`, *not* part of the output.

# Answer
> 2 votes
# Microsoft Excel / Google Sheets, 22 Bytes

Anonymous Worksheet function that takes no input and outputs `1987` in Microsoft Excel, and `2006` in Google Sheets

```
=IfError(M(2006),1987)

```

# Answer
> 0 votes
## Perl 5 & Perl 6 (2 years)

```
my $a=2015;my @a=1994;print $a[0],"\n"

```

First release of Perl 5 was in 1994

First official release of Perl 6 was in 2015

# Answer
> 0 votes
## Python 1.6, 2.7.17, and 3.8, 39 bytes

The (currently) latest versions of each major release.

```
print(2000+(str(2>1)!='1')*round(39/2))

```

Try them online!

Here, I'll evaluate them until the most important parts.

Python 1.6:

```
print(2000+('1'!='1')*round(39/2))

```

Python 2.7.17:

```
print(2000+True*round(19))

```

Python 3.8

```
print(2000+True*round(19.5))

```

---
Tags: code-challenge, polyglot, rosetta-stone
---


title: Simulate a random walk

text:
# Question
Title: Simulate a random walk
# Context

In this challenge, a random walk is a stochastic process in which a particle at a position with integer coordinates (or a drunk man) moves at each integer time step (that is, at `t = 1, 2, 3, ...`) by taking a step of size `1` to any of its neighbouring positions, with the direction of the step being aligned with the axis, but chosen randomly

For example, in one dimension, we may have the following table of positions at the given times, starting at `t = 0` with the initial condition `p = 2`:

```
----------
| t |  p |
----------
| 0 |  2 |
----------
| 1 |  3 |
----------
| 2 |  2 |
----------
| 3 |  3 |
----------
| 4 |  2 |
----------
| 5 |  1 |
----------
| 6 |  0 |
----------
| 7 | -1 |
----------
| 8 |  0 |
----------
| 9 | -1 |
----------
   ...

```

# Task

Your task is to simulate a random walk in `n` dimensions from a supplied starting point, until the drunk man arrives at the origin **for the first time**, i.e. when we reach the point with coordinates `[0,0,...,0]` for the first time. *If we start at the origin, nothing has to be done because we already arrived.*

In the example above, the program would have stopped at `t = 6`.

You can take whatever probability distribution you want over the possible directions to go, so long as, for any position and any direction, there is a non-zero probability of that direction being picked.

Notice that your program must work for an arbitrary dimension, even though in practice, for higher dimensions it will not stop in a reasonable amount of time.

# Input

Any initial position with integer coordinates, of any positive size (so 1 or more). You can infer the dimensions of the random walk from the size of the input or you can take the dimension as an extra input. If you do, assume the dimension given matches the size of the initial position.

Input of initial position can be in any sensible format, including:

* a list of integers
* one input coordinate per function argument

Your program should work for any `n`, even though in practice it will time out for `n >= 3` unless you are incredibly lucky :)

# Output

You should return or print any of the following:

* all the intermediate positions occupied by the particle until the end of the random walk
* all the intermediate steps taken by the particle until the end of the random walk

The intermediate positions can be displayed in any human-readable way, as long as no two different positions are displayed the same way. Same applies to intermediate steps taken.

# Test cases

These should finish on TIO often:

```
[3]
[1, 0]
[0, -2]
[1, 1]
[-1,1]
[0]
[0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]

```

These will probably timeout, but that is fine as long as your program runs:

```
[1, 0, 0, 0]
[0, 0, 3, 0, -2, 100]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

```

You can check this reference program where I set the seed so that you can see it terminating for a random walk of 3 dimensions.

---

This is so shortest submission in bytes, wins! If you liked this challenge, consider upvoting it... And happy golfing!

# Answer
# Jelly,  ~~13~~  12 bytes

```
LXṬ,N$X+µẸÐ¿

```

A monadic Link accepting a list of integers which yields a list of lists of integers.

**Try it online!**

How?

```
LXṬ,N$X+µẸÐ¿ - Link: list of integers, p (length d)
          Ð¿ - collect up while...
         Ẹ   - ...condition: any? (when we reach [0]*d this does not hold
        µ    - ...do: the monadic chain - i.e. f(v); initially v=p:
L            -   length (of v) = d
 X           -   random integer (in range [1,d])
  Ṭ          -   untruth     e.g. 4 -> [0,0,0,1]
     $       -   last two links as a monad:
    N        -     negate              [0,0,0,-1]
   ,         -     pair                [[0,0,0,1],[0,0,0,-1]]
      X      -   random choice         [0,0,0,1] OR [0,0,0,-1]
       +     -   add (to v)  e.g. [0,0,0,-1] + [4,2,3,2,5] = [4,2,3,1,5]

```
> 5 votes

# Answer
# Wolfram Language (Mathematica), 99 bytes

```
#//.i_/;Union@i!={0}:>(i+RandomChoice@Select[Tuples[{-1,1,0},d=Tr[1^i]],#~Count~0==d-1&])&&Print@i&

```

Try it online!
> 3 votes

# Answer
# Python 3, ~~92~~ ~~87~~ ~~82~~ ~~81~~ 75 bytes

Input: the starting position (as list) and number of dimensions.

```
def f(p,d):
 r=id(f)
 while any(p):p[r%d]+=r//d%2*2-1;print(p);r=hash((r,))

```

Try it online!

## Explanation

I created my own custom random generator as follow:

* `r=id(f)`: seed the generator - this is the source of randomness since the ID of `f` is different each time the program runs.
* `r=hash((r,))` generates the next random by hashing the tuple `(r,)`. This is the shortest I could find, as `hash(r)` just returns `r`, while `hash([r])` is not valid due to list not being hashable.

This ended up being shorter than using `random` or `time` module.

For each iteration, the program simply picks a random coordinate and add `1` or `-1` (randomly) to it.

* `r%d` is a random number between `0` and `d-1` inclusive, used to pick a random coordinate.
* `r//d%2` is a random number in \\$\\{0,1\\}\\$, and `(r//d%2)*2-1` maps it to \\$\\{-1,1\\}\\$.

`any(p)` checks if `p` has some non-zero coordinate, in which case the programs continue to run.

In case `id` and `hash` are not considered "random" enough, here is the same program but using `time` for randomness

# Python 3, ~~92~~ ~~87~~ ~~82~~ 81 bytes

*-1 byte thanks to @RGS*

```
import time
t=time.time_ns
def f(p,d):
 while any(p):p[t()%d]+=t()%2*2-1;print(p)

```

Try it online!
> 3 votes

# Answer
# Perl 6, 48 bytes

```
{{[(.rand+|0=>(-1,1).pick){^$_}Z+@$_]}...*.none}

```

Try it online!

Returns all intermediate positions.

### Explanation

```
{                                              }  # Anonymous list
                                      ...  # Create sequence
 {                                   }  # Compute next item by
   (        =>           )  # Create pair with
    .rand+|0                # random integer in [0,dim) as key
              (-1,1).pick   # -1 or 1 as value
                          {^$_}  # Lookup values [0,dim)
                               Z+@$_   # Add to previous vector
  [                                 ]  # Store in array
                                         *.none  # Until all coords are zero

```
> 3 votes

# Answer
# C (gcc), 161 bytes

```
z(a,l,r)int*a;{for(r=0;l--;)r|=a[l];l=r;}p(a,l)int*a;{for(puts("");l--;)printf("%d,",*a++);}f(a,l)int*a;{for(srand(&l);p(a,l),z(a,l);)a[rand()%l]+=1-rand()%2*2;}

```

Prints all coordinates.

Example output:

```
0,-2,
1,-2,
1,-1,
1,0,
2,0,
1,0,
0,0,

```

*-1 byte thanks to ceilingcat!*

Try it online!
> 2 votes

# Answer
# Charcoal, 25 bytes

```
Ｗ⌈↔θ«≔‽Ｌθι§≔θι⁺§θι⊖⊗‽²⟦Ｉθ

```

Try it online! Link is to verbose version of code. Explanation:

```
Ｗ⌈↔θ«

```

Repeat until the origin is reached. (`Ｗ⊙θκ«` also works for the same byte count.)

```
≔‽Ｌθι

```

Pick a random dimension.

```
§≔θι⁺§θι⊖⊗‽²

```

Move one step randomly along that dimension.

```
⟦Ｉθ

```

Output the new coordinates. The  double-spaces the coordinates for clarity, but if that's not required then it could be removed.

Bonus program:

```
ＪＮＮＷ∨ⅈⅉ✳⊗‽φ¹@

```

Try it online! Takes two dimensions only. Sample output:

```
    |
 ||----
----@
||
|-

```
> 2 votes

# Answer
# 05AB1E, 15 bytes

```
[=D_P#āDΩQD(‚Ω+

```

Inspired by *@JonathanAllan*'s Jelly answer.

Try it online.

**Explanation:**

```
[           # Start an infinite loop:
 =          #  Print the current list with trailing newline (without popping),
            #  (which will use the implicit input-list in the very first iteration)
  D         #  Duplicate the current list
   _        #  Check for each value whether it is 0
            #   i.e. [0,4,0] → [1,0,1]
    P       #  And if all are truthy:
     #      #   Stop the infinite loop
  ā         #  Push a list in the range [1,length] (without popping)
            #   i.e. [0,4,0] → [1,2,3]
   D        #  Duplicate it
    Ω       #  Pop and push a random value from this list
            #   i.e. [1,2,3] → 3
     Q      #  Check for equality; the random 1-based position becomes 1, the others 0
            #   i.e. [1,2,3] and 3 → [0,0,1]
      D(‚   #  Pair it with a negative copy of itself
            #   i.e. [0,0,1] → [[0,0,1],[0,0,-1]]
         Ω  #  Pop and push either of these two lists
            #   i.e. [[0,0,1],[0,0,-1]] → [0,0,-1]
          + # And the values at the same indices
            #  i.e. [0,4,0] + [0,0,-1] → [0,4,-1]

```
> 2 votes

# Answer
# PowerShell, ~~68~~ ~~63~~ ~~61~~ 57 bytes

-4 bytes thanks to mazzy

```
param($n,$d)for(;$n-ne0){$n[(random $d)]+=1,-1|random;$n}

```

Try it online!

Less Ugly Form for 2 extra bytes.

The neat part of this answer is the for conditional, `$n-ne0`. When you apply comparison operations to arrays, it applies it to each element and acts as a filter, in this case filtering out all 0s. If we filter everything out (i.e., we're at `(0,0,...,0)`), we get an empty array and those are considered false. As a side note, for the singleton case, you have to explicitly cast the parameter to a list. Otherwise, it wants to play ball as an int which doesn't go over well.

I reread the comments and noticed you didn't need to print the initial config, saving 5 bytes. This now means things that start at the origin return nothing but that seems up to spec.
> 2 votes

# Answer
# Ruby, 46 bytes

`p(l)` prints the contents of `l` and then returns the same array as well, making things very convenient as we can wrap the print statement into the termination condition.

```
->l,d{l[rand d]+=rand(2)*2-1until[]==p(l)-[0]}

```

Try it online!
> 2 votes

# Answer
# Python 3, ~~105~~ \\$\cdots\\$ ~~89~~ 86 bytes

Saved 3 bytes thanks to Surculose Sputum!!!

```
from random import*
def f(p,l):
 while any(p):p[randrange(l)]+=choice((-1,1));print(p)

```

Try it online!
> 1 votes

# Answer
# BATCH, ~~563 560 539 509~~ 653 bytes

```
@ECHO OFF
Setlocal EnableDelayedExpansion
Set "#=Set "
!#!/P N=D
!#!"F=For /L "
!#!I= in (1,1,
!#!D=) Do (
!#!E=) ELSE (
!#!C=CALL :
!#!Y=2
%F%%%A%I%!N!%D%
!#!O%%A=0
!#!/P S%%A=Ax%%A
!#!H%%A=!S%%A!)
%F%%%A%I%50000%D%
!#!v=0
!C!R U N
!C!M S!U! H!U!
!#!]=@
%F%%%B%I%!N!%D%
!#!"]=!]!!S%%B!,"
IF %%B==!N! !#!]=!]:~,-1!
IF !O%%B!==!S%%B! !#!/A v+=1
IF !v!==!N! GOTO :E
)
ECHO(!]!
)
:E
ECHO(!]!
pause
:M
!C!R R Y
!C!R P Y
IF !R!==1 (IF !%1! LEQ 0 (IF !P!==1 (!#!/A %1+=1%E%!#!/A %1-=1)%E%!#!/A %1-=1)%E%IF !%1! GEQ !%2! (IF !P!==2 (!#!/A %1-=1%E%!#!/A %1+=1)%E%!#!/A %1+=1))
Exit /B
:R
!#!/A %1=!random! %%!%2! +1
Exit /B

```

**Update** At the cost of alot of bytes, I corrected the issues with zero chance for movement along any axis under the previous conditions, and through the use of an additional random test in an Ugly, byte hungry conditional statement still biased movement (In a non zero manner compliant with the terms outlined). also modified the output to match the specified form.

Example Output
> 1 votes

# Answer
# JavaScript (ES6),  ~~63~~  62 bytes

```
f=a=>a.join``==0?[a]:[a,...f(a.map(x=>x+~-(3*Math.random())))]

```

Try it online!
> 1 votes

# Answer
# Wolfram Language (Mathematica), ~~83~~ ~~79~~ 75 bytes

```
For[r=RandomInteger;i=#,!0==##&@@i,j=r@{1,Tr[1^i]};i[[j]]+=2r[]-1,Print@i]&

```

Try it online!

Omits the last result (which is the origin anyway).
> 1 votes

# Answer
# Octave, 74 bytes

```
x=input('');do disp(x),x(randi(size(x)))+=2*randi([0 1])-1;until~x;disp(x)

```

Try it online!
> 1 votes

---
Tags: code-golf, random
---


title: Is it a valid number theory expression?

text:
# Question
Title: Is it a valid number theory expression?
A number theory expression contains:

```
There exists at least one non-negative integer (written as E, existential quantifier)
All non-negative integers (written as A, universal quantifier)
+ (addition)
* (multiplication)
= (equality)
>, < (comparison operators)
&(and), |(or), !(not)
(, ) (for grouping)
variable names(all lowercase letters and numbers, not necessary one char long)

```

However, it has some more limitations:

* Arithmetic expressions should be syntactically valid. Here we only treat `+` as addition, not positive, so `+` and `*` should be surrounded by two number expressions
* brackets should be well paired
* `<` `=` `>` should be surrounded by two number expressions
* `&` `|` `!` are fed with logical expressions
* `E` and `A` are fed with a variable and an expression
* For `E` and `A`, there should be a reasonable affected range. (\*)

For (\*): We write `Ax Ey y>x & y=x`, `Ax Ey y>x & Ey y=x` as well as `Ax Ey y>x & Ax Ey y=x`, which mean `Ax (Ey ((y>x) & (y=x)))`, `Ax ((Ey (y>x)) & (Ey (y=x)))` and `(Ax (Ey (y>x))) & (Ax (Ey (y=x)))`; however we don't write `Ax Ey Ax x=y` or `Ax Ey x<y & Ex x>y`. That means there should be some way to add brackets, so everywhere any variable is at most defined for once, and anywhere that use the variable has it defined.

## Input

You'll be given an expression with these chars (invalid chars won't appear), only split when necessary (two variable names together), split after each quantifier variable, or each symbols are separated. No invalid symbol.

## Output

Check whether it's a **valid** number theory expression. Either true/false or multi/one are allowed.

## True samples (each symbol separated)

```
E a E b a < b
E b A x b < x & A x b > x
E b A x b < x & b > x
A b b + b < ( b + b ) * b | E x x < b
E x E y y < x & E x2 y = x2
E 1 A x x * 1 = x & E 2 2 * 2 = 2 + 2 & 2 > 1 & E x x + 1 = x * x * 2
E x E y y = y & y + y * y = y

```

## False samples

```
E a E b a + b < c
E a E b b * ( a > a ) + b
A a A b ( a = b ) = b
A x A y A z A y x < z
E x E y y < x & E x y = x
E E x x = x
E x ( x < x
E x = x

```

## Undefined behavior samples

```
E C C = C
AA x x = x
Ex = x

```

Shortest code in bytes win

Symbol definition: It's a resexpr

```
numexpr({s},∅) = s
numexpr(a∪b,c∪d) = numexpr(a,c) + numexpr(b,d)
numexpr(a∪b,c∪d) = numexpr(a,c) * numexpr(b,d)
numexpr(a,c) = ( numexpr(a,c) )
boolexpr(a∪b,c∪d) = numexpr(a,c) = numexpr(b,d)
boolexpr(a∪b,c∪d) = numexpr(a,c) < numexpr(b,d)
boolexpr(a∪b,c∪d) = numexpr(a,c) > numexpr(b,d)
boolexpr(a∪b,c∪d) = boolexpr(a,c) & boolexpr(b,d)
boolexpr(a∪b,c∪d) = boolexpr(a,c) | boolexpr(b,d)
boolexpr(a,c) = ! boolexpr(a,c)
boolexpr(a,c) = ( boolexpr(a,c) )
boolexpr(a-{s},c∪{s}) = E s boolexpr(a,c) if s∉c
boolexpr(a-{s},c∪{s}) = A s boolexpr(a,c) if s∉c
resexpr = boolexpr(∅,a)
a,b,c,d mean sets, s mean non-empty strings containing a-z0-9

```

## Notes

* You don't need to check whether the expression is **true**, as it's usually impossible

# Answer
# APL (Dyalog Unicode), ~~318~~ ~~317~~ 319 bytesSBCS

```
∨/{(4=⊃⍵)>≢⊃1⌽⍵}¨{1=≢⍵:⍵⋄⊃,/(⊂⍵)∇{⊃,/,(⍺⍺⍵↑⍺)∘.{c←⊃¨⍺⍵⋄w←⊃,/⊃¨u v←1↓¨⍺⍵
(⊂c)∊t←↓10 2⍴⎕A⍳'AOBAJACKANEADMLDJDGK':⊂(2,u)(1w 0)(3,v)(1u 0)(5(⊃u)⍬)(4w⍬)(6,u)(4,v)(7,v)(4,u)⊃⍨t⍳⊂c
6 4≡c:⊂4,u,¨v
9 1≡c:(2⊃v)↑⊂8,v
8 4≡c:(a∊3⊃⍵)↓⊂4(a~⍨⊃v)((3⊃⍵),a←⊃u)
⍬}⍺⍺⍵↓⍺}¨⍳¯1+≢⍵}{⌈/c←(⊃⍵)∊¨¯1⌽'()!',↓4 3⍴' &|=<>+* AE':8+⊃⍸c⋄1(⊂⍵)1}¨' '(≠⊆⊢)⍞

```

Try it online!

-1 byte thanks to @Adám.

+2 bytes because the code wrongly accepted `E ( a ) a = a`. Fixed by adding a "simple" flag to the Num node, which is 1 right after tokenization but becomes 0 after any kind of merging. `TQuant Num -> Quant` rule is accepted only if "simple" is 1.

Full program. Takes a line of input (each symbol separated with a space) from stdin, and prints 1 if it can be parsed successfully, 0 otherwise.

### How it works: the grammar & parsing

I manually dissected all the grammar rules into two-branch rules, e.g. the parenthesizing rule

```
"(" Num ")" -> Num

```

became two rules

```
"(" Num -> NumP
NumP ")" -> Num

```

with `NumP` being a new node type. Also, I omitted the last part of the `Num` node, as it is always an empty set.

```
(Num ids,?) [+*] -> (NumR ids)
(NumR ids) (Num ids2,?) -> (Num (ids+ids2),0)
"(" (Num ids,?) -> (NumP ids)
(NumP ids) ")" -> (Num ids,0)
(Num ids,?) [=<>] -> (BoolN ids,[])
(BoolN ids,ids3) (Num ids2,?) -> (Bool (ids+ids2),ids3)
(Bool ids,ids2) [&|] -> (BoolR ids,ids2)
(BoolR ids,ids3) (Bool ids2,ids4) -> (Bool (ids+ids2),(ids3+ids4))
"!" (Bool ids,ids2) -> (Bool ids,ids2)
"(" (Bool ids,ids2) -> (BoolP ids,ids2)
(BoolP ids,ids2) ")" -> (Bool ids,ids2)
[EA] (Num id,1) -> (Quant id)
(Quant id) (Bool ids,ids2) -> (Bool (ids-id),(ids2+id)) if id not in ids2

```

Using these rules, I could tackle the ambiguous parsing problem as follows:

1. Split the given list of tokens into two chunks.
2. Recursively get all possible parses for the two chunks.
3. Test all combinations of parses to gather all possible derived parses.
4. Repeat 1-3 for all possible splits, and gather all results.

The algorithm is exponential in the number of tokens, so the two longest test cases are excluded from the tests.

### Original version with comments

```
⍝ Constants to classify the grammar node type
Num NumR NumP Bool BoolN BoolR BoolP Quant TQuant TParenL TParenR TNot TBool2 TCmp TNum2←⍳15

⍝ Split given string by spaces, and convert to a list of grammar nodes
tokenize←{
  words←(' '∘≠⊆⊢)⍵  ⍝ split by spaces
  {
    class←(⊃⍵)∊¨'AE' '(' ')' '!' '&|' '=<>' '+*'
    ⌈/class: 8+⊃⍸class  ⍝ Single-char tokens into respective nodes
    Num(⊂⍵)1  ⍝ An identifier is a Num node
  }¨words  ⍝ wrap each word into tokens
}

⍝ Takes two nodes, and gives a new node if valid, ⍬ otherwise
match←{
  class←⊃¨⍺⍵
  Num TNum2≡class: ⊂NumR(2⊃⍺)
  NumR Num≡class: ⊂Num((2⊃⍺),2⊃⍵)0
  TParenL Num≡class: ⊂NumP(2⊃⍵)
  NumP TParenR≡class: ⊂Num(2⊃⍺)0
  Num TCmp≡class: ⊂BoolN(2⊃⍺)⍬
  BoolN Num≡class: ⊂Bool((2⊃⍺),2⊃⍵)⍬
  Bool TBool2≡class: ⊂BoolR(2⊃⍺)(3⊃⍺)
  BoolR Bool≡class: ⊂Bool((2⊃⍺),2⊃⍵)((3⊃⍺),3⊃⍵)
  TNot Bool≡class: ⊂Bool(2⊃⍵)(3⊃⍵)
  TParenL Bool≡class: ⊂BoolP(2⊃⍵)(3⊃⍵)
  BoolP TParenR≡class: ⊂Bool(2⊃⍺)(3⊃⍺)
  ⍝ Valid only if "simple" flag of Num node is 1
  TQuant Num≡class: (3⊃⍵)↑⊂Quant(2⊃⍵)
  ⍝ Valid only if quantified variable is not already quantified
  Quant Bool≡class: (~(2⊃⍺)∊3⊃⍵)↑⊂Bool((2⊃⍵)~2⊃⍺)((3⊃⍵),2⊃⍺)
  ⍬
}

⍝ Given a list of tokens, returns an array of possible parses
⍝ Split in all possible ways and check for at least one split is valid
parse←{
  ⍝ Single token: no need to parse
  1=≢⍵:⍵
  splits←⍳¯1+≢⍵
  ⍝ Concatenate parses based on all possible splits
  ⊃,/(⊂⍵)∇{
    left←⍺⍺ ⍵↑⍺
    right←⍺⍺ ⍵↓⍺
    ⍝ Test all possible combinations of left/right parses
    ⊃,/,left ∘.match right
  }¨splits
}

⍝ Test if one of the parses is Bool with no free variables
test←{
  ∨/{
    Bool≠⊃⍵:0
    0=≢2⊃⍵
  }¨⍵
}

⍝ The solution is the chain of three functions defined above
test∘parse∘tokenize

```

Try it online!
> 7 votes

---
Tags: code-golf, parsing
---