Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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 you 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!

share|improve this question
    
Am I missing something here? Seems like you could enumerate through all programming languages with IO and just use "println(...)". – Myridium yesterday
    
@Myridium There are two problems with that. 1. That's not valid in a lot of languages and 2. Each program must print out the language year and nothing more. A trailing newline (windows style or *nix style) is allowed. – DJMcMayhem yesterday
1  
(casually inserts Whitespace code to print 2003 in basically every single submission) – Value Ink 23 hours ago
4  
"You may not use any builtins that give you information about the current version of the language you are using." My emphasis. May I look for the build date in the interpreter file? – Adám 20 hours ago
1  
I don't think this one is a duplicate at all. Even if it is, this challenge should be accepted as the 'original' because unlike the other one, this challenge encourages users to go out and learn about what they're using. – tuskiomi 13 hours ago

12 Answers 12

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)
share|improve this answer
1  
... Wow. It still amazes me how well some people know their languages. It's like looking back through time... – wizzwizz4 11 hours ago
    
Does python 0 support try/except?? – OldBunny2800 8 hours ago
    
@OldBunny2800 Amazingly, yes it does – Sp3000 3 hours ago

6 years

2007}2015!@'9002'oooo;

R"2014";

$'main'
 \-[2005]o#

 x
x%"2010"x
 x

Yay for 2D languages with explicit entry points.

2005: Rail

Rail looks for a line starting with $'main' as its entry point, so everything except this bit is ignored:

$'main'
 \-[2005]o#

This simply pushes the string 2005 and outputs it before terminating the program.

2007: GolfScript

Golfscript pushed the initial 2007 and the } "comments out" the entire rest of the program, so the 2007 is printed.

2009: ><>

For ><>, only the first line matters. 2007 pushes the individual digits, } rotates the stack, 2015 pushes some more digits and ! skips the @. Now the relevant program:

'9002'oooo;

'9002' pushes the characters corresponding to those digits, oooo outputs them, ; terminates the program.

2010: Cardinal

For Cardinal, % creates four instruction pointers, one in each cardinal direction. Here, the only relevant part of the program is:

 x
x%"2010"x
 x

The xs remove three of those pointers and the other one prints 2010 before being removed as well.

2014: Fission

For Fission, only UDLR mark entry points, in this case the R on the second line. The only relevant part of the program is:

R"2014";

The created atom simply prints 2014 and the ; destroys it and terminates the program.

2015: Labyrinth

Labyrinth sees only the first line since there is no connection to the remainder of the program. 2007 pushes this number, } shifts it to the auxiliary stack. 2015 pushes this number, then ! prints it and @ terminates the program.

share|improve this answer

3 languages; K, J201, Dyalog APL 7.1; 8 bytes

1993+1^2

1993 plus...

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

J: 12 = 1; 1994

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

share|improve this answer
    
Very nice! Think you could combine more of the Iverson languages? – miles 22 hours ago
    
@miles Get's tough with K, and APL2/APLX/APL*PLUS are too similar. – Adám 22 hours ago
    
@miles Do you know of a J version from 2000? If so, we can do 2e3+?1 with Dyalog 9.0.1. – Adám 22 hours ago
    
Another cool prospect is X^Y for some numbers X and Y, as ^ is power in J, but LCM in APL. – Adám 22 hours ago
1  
I've found a page of features over releases with their dates up to 2000, jsoftware.com/release/status.htm – miles 22 hours ago

5 years

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

1989: C89[1], 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[2]: 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.
share|improve this answer

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
share|improve this answer

5 years, Go 1.0, 1.1, 1.4, 1.5, 1.6: 285 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 v()(s string){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 Sprintf("%c",0xd800)!="\ufffd"{s="2"}
return}
func main(){Print("201"+v())}

Ungolfed and commented:

package main

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

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

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.

share|improve this answer
3  
This could be a fun challenge if it involves identifying bugs/changes in operators between versions – miles yesterday
1  
@TuukkaX It works for me in both Python 2.7.12 and Python 3.5.1 on Fedora 24. – miles 23 hours ago
1  
Can't you do '2010'if 3/2>1else'2015' instead? – Qwerp-Derp 21 hours ago
1  
print('2015'if 1/2else'2010') - same idea, 1/2 evaluates to 0 (falsy value) in Python2 and to 0.5 in Python3. – Jakube 19 hours ago
5  
Or us math: print(int(2010+1/2*10)) – Jakube 19 hours ago

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: [10 11]
;        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"
share|improve this answer

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.

share|improve this answer

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.

share|improve this answer

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.

share|improve this answer

27 Dyalog APL Classic versions, 99 bytes

⍎¯5↑b↑⍨20+1⍳⍨'Created'⍷b←⎕NREAD¯1 82,⎕NSIZE¯1⎕NTIE⍨'/dyalog.exe',⍨2⎕NQ'.' 'GetEnvironment' 'DYALOG'

This ties the currently running interpreter executable, reads it raw, then digs out the internal build year.

This is valid according to the literal reading of the OP. However, I've asked about it since it is obviously not in the spirit.

share|improve this answer
5  
This seems like a borderline violation of the rule that you're not allowed to fetch built-in release year information. – Martin Ender 19 hours ago
    
@MartinEnder It doesn't say so. – Adám 18 hours ago
1  
After re-reading you're right. You still could have waited for the OP to get back to your request for clarification before posting an answer of which you're clearly aware that it is probably not in the spirit of the challenge (otherwise, I think you wouldn't have asked in the first place). – Martin Ender 18 hours ago
3  
In my mind, "the release date of the current version" counts as "information about the current version". This is exactly why I included this rule. – DJMcMayhem 15 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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