182
\$\begingroup\$

Isn't it annoying when you find a piece of code and you don't know what language it was written in? This challenge attempts to somewhat solve this.

Challenge

You will have to write a program that when run in two different languages, will output the string:

This program wasn't written in <language program compiled/interpreted in>, it was built for <other language the program can be run in>!

  • In the output, language names should have official capitalization. eg: CJam, C++

  • Neither program should take any input from the user.

  • When run in both languages, output should be to stdout or equivalent.

  • There should be no output to stderr in either program.

  • You may use comments in either language.

  • Two different versions of the same language count as different languages.

    • If this is done, the program should output the major version number, and if running on two different minor versions, should report the minor version also.

    • You should not use prebuilt version functions (this includes variables that have already been evaluated at runtime).

Example output:

Perl and Ruby:

  • Perl: This program wasn't written in Perl, it was built for Ruby!

  • Ruby: This program wasn't written in Ruby, it was built for Perl!

Python and C:

  • Python: This program wasn't written in Python, it was built for C!

  • C: This program wasn't written in C, it was built for Python!

Python 2 and Python 3:

  • Python 2: This program wasn't written in Python 2, it was built for Python 3!

  • Python 3: This program wasn't written in Python 3, it was built for Python 2!

Python 2.4 and Python 2.7:

  • Python 2.4: This program wasn't written in Python 2.4, it was built for Python 2.7!

  • Python 2.7: This program wasn't written in Python 2.7, it was built for Python 2.4!

This is code golf so the shortest code in bytes wins.

\$\endgroup\$
  • 2
    \$\begingroup\$ "Two different versions of the same language count as different languages." So tricking like with C pre and past 99 comments is valid? easy ^^ \$\endgroup\$ – Zaibis Sep 3 '15 at 13:54
  • 1
    \$\begingroup\$ Added it, it feels paradoxical but fits to your rules. \$\endgroup\$ – Zaibis Sep 3 '15 at 14:48
  • 1
    \$\begingroup\$ No one's doing a Whitespace/Python polyglot? \$\endgroup\$ – Not that Charles Sep 4 '15 at 15:22
  • \$\begingroup\$ nevermind. Saw the 23 implementation \$\endgroup\$ – Not that Charles Sep 4 '15 at 15:26
  • \$\begingroup\$ Does relying on the program to be run with a certain interpreter count as input? that is, switching on argv[0]? \$\endgroup\$ – cat Oct 28 '16 at 12:10

110 Answers 110

8
\$\begingroup\$

VB6 / ES6 – 115 bytes

VB6

l="VB"
o="ES"
'';[l,o,MsgBox]=[o,l,alert]
MsgBox("This program wasn't written in "+l+"6, it was built for "+o+"6!")

ES6

l="VB"
o="ES"
'';[l,o,MsgBox]=[o,l,alert]
MsgBox("This program wasn't written in "+l+"6, it was built for "+o+"6!")
\$\endgroup\$
  • \$\begingroup\$ VBScript is not at version 6. The latest is 5.8. \$\endgroup\$ – peter ferrie Mar 15 '18 at 4:21
  • 1
    \$\begingroup\$ @peterferrie Thanks, but that's irrelevant. VB6 stands for Visual Basic 6, not VBScript 6. \$\endgroup\$ – Toothbrush Mar 15 '18 at 17:18
7
\$\begingroup\$

Are solutions with more than two languages allowed? If so:

Python 3 / JavaScript / jq, 284 bytes

0//1|"\(".__len__();console={'log':lambda x:print(x.replace('JavaScript','Python 3').replace('jq','JavaScript'))}#")"|
"\(";console['log']('This program wasn\u0027t written in JavaScript, it was built for jq!');0//1#"|"This program wasn't written in jq, it was built for Python 3!")"

Highlighted for Python:

0//1|"\(".__len__();console={'log':lambda x:print(x.replace('JavaScript','Python 3').replace('jq','JavaScript'))}#")"|
"\(";console['log']('This program wasn\u0027t written in JavaScript, it was built for jq!');0//1#"|"This program wasn't written in jq, it was built for Python 3!")"

Highlighted for JavaScript:

0//1|"\(".__len__();console={'log':lambda x:print(x.replace('JavaScript','Python 3').replace('jq','JavaScript'))}#")"|
"\(";console['log']('This program wasn\u0027t written in JavaScript, it was built for jq!');0//1#"|"This program wasn't written in jq, it was built for Python 3!")"

No idea how to start explaining the jq part; just know that the string interpolation syntax in jq works as a "string inside string" of sorts: between "\(" and ")", jq is in a string inside a string, while Python and JavaScript consider them individual strings.

Using jq -n -r, python3 and node.

\$\endgroup\$
6
\$\begingroup\$

Perl/JavaScript ES6, 170 bytes

$a='Perl',$b='JavaScript';/1/&&($a=[$b,$b=$a].shift());$_="This program wasn't written in $a, it was built for $b!";/1/?console.log($_.replace(/\$./g,$r=>eval($r))):print

Again abusing regular expressions, but this time the fact that /1/ is truthy in JavaScript (because it's a RegExp object) and falsy in Perl (because $_ is empty) to switch the variables and run the correct print statement.

Note: This is ES6 JavaScript to work around Perl throwing a syntax error.

\$\endgroup\$
6
\$\begingroup\$

TeX / BASH - 192 bytes

echo "This program wasn't written in bash, it was built for TeX!";: "\output{\setbox0\hbox{\box255}\setbox0\vbox{This program wasn't written in \TeX, it was built for bash!}\shipout\box0}\end"

Trick is basically in the : "...." which lets bash do nothing with what comes inside the " ". TeX on the other hand just print it's own stuff onto a white paper. I know I could save 1 byte by writing "TeX" instead of "\TeX", but I wont, this looks much nicer: enter image description here

Inspired by http://pts.szit.bme.hu

Bonus:

TeX / many shells - 244 bytes

S=$(ps | grep `echo $$`$5 | awk '{ print $4$6 }');echo "This program wasn't written in $S$6, it was built for TeX!";: "\output{\setbox0\hbox{\box255}\setbox0\vbox{This program wasn't written in \TeX, it was built for shells!}\shipout\box0}\end"

This can in addition be run with dash, sh, ksh, et. al and will produce:

sheß@donald:~$ bash sh.sh
This program wasn't written in bash, it was built for TeX!
sheß@donald:~$ dash sh.sh
This program wasn't written in dash, it was built for TeX!
sheß@donald:~$ sh sh.sh
This program wasn't written in sh, it was built for TeX!
\$\endgroup\$
  • \$\begingroup\$ Finally:), I was already worried that no one would appreciate that \$\endgroup\$ – sheß Sep 9 '15 at 12:07
6
\$\begingroup\$

Java/C, 418 Bytes

It might not have been a wise decision to use Java, nonetheless here's my solution:

//\u000a/*
#include <stdio.h>
#define public
#define static }
#define String int i,char*v
#define args
#define class
#define long g(){int
#define A struct{struct{int(*printf)();}out;}System={printf};f()
#define true 0
//*/
public class A{public static void main(String[]args){int c=true==(0==0)?1:0;System.out.printf("This program wasn't written in %s, it was built for %s!",c==0?"C":"Java",c==0?"Java":"C");}long f;}

Turns out Java and C are quite close. Except java is a lot more verbose and has a lot of keywords C doesn't need. And Java doesn't like the mixture of int's and booleans.

Annotated version

//\u000a/*                  /* \u000a gets replaced by a newline by javac
                               -> single line comment in C, multiline in java */
#include <stdio.h>          /* include needed, so I can use printf as function pointer */
#define public
#define static }
#define String int i,char*v /* make main declaration C compatible */
#define args
#define class
#define long g(){int        /* to remove closing bracket for `class {}` */
#define A struct { \        /* System.out.printf for C */
              struct { \
                  int (*printf)(); \
              } out; \
          } System = { printf }; \
          f()
#define true 0              /* Nothing is true, everything is permitted */
//*/                        /* single line comment in C, ends java multiline comment */
public class A {
    public static void main(String[] args) {
        int c = true == (0 == 0) ? 1 : 0; /* 1 for Java, 0 for C */
        System.out.printf("This program wasn't written in %s, it was built for %s!",
            c == 0 ? "C" : "Java",
            c == 0 ? "Java": "C");
    }
    long f; /* extra member, in java. gets redefined in C to get rid of the last } */
}

There might be some possibilites to cut off a few bytes here and there.

\$\endgroup\$
  • \$\begingroup\$ I think you can safely remove the v after #define String int i, char* \$\endgroup\$ – YoYoYonnY Dec 12 '15 at 22:04
6
\$\begingroup\$

Perl/Tcl 171 bytes

#\
sub set{eval"\$$_[0]=\"$_[1]\""}sub puts{}
set a, "This program wasn't written in";
set b, "l, it was built for";
#\
print"$a Per$b Tcl!\n"||
puts "${a,} Tc${b,} Perl!"

No trailing semicolon or newline. This exploits Tcl comments being, well, odd!

\$\endgroup\$
6
\$\begingroup\$

Perl/PHP, 99 bytes

<?$p=erl;">;$p=HP#"
;$o=$p^erl^HP;print"This program wasn't written in P$o, it was built for P$p!";

For PHP, I assume the default interpreter settings, as they are without any ini. If you are uncertain, you may disable your local ini with -n as in php -n script.php.

\$\endgroup\$
  • \$\begingroup\$ On Ubuntu 15.04, perl does what's expected, but command-line php 5.6.4-4ubuntu6.2 just returns a verbatim copy of the input, even with -f or -F. Doesn't it work on command line? \$\endgroup\$ – Stéphane Gourichon Sep 10 '15 at 7:22
  • 1
    \$\begingroup\$ @StéphaneGourichon you will need to explicitly enable the short_open_tag in the php config file. Although it is enabled by default, all of the sample config files disable it. \$\endgroup\$ – primo Sep 11 '15 at 2:36
  • \$\begingroup\$ I'd rather not require administrator-level privilege just for this. I give up here since adding ` -d display_errors=Off` or =0 does not clean the output. php -d short_open_tag=On polyglot.php PHP Notice: Use of undefined constant erl - assumed 'erl' in polyglot.php on line 1 PHP Notice: Use of undefined constant erl - assumed 'erl' in polyglot.php on line 2 PHP Notice: Use of undefined constant HP - assumed 'HP' in polyglot.php on line 2 This program wasn't written in PHP, it was built for Perl! \$\endgroup\$ – Stéphane Gourichon Sep 11 '15 at 8:33
  • \$\begingroup\$ @StéphaneGourichon "I'd rather not require administrator-level privilege just for this." To be honest, I assumed most people would be running it from their own rig. short_open_tag: default value On. error_reporting: default value E_ALL & ~E_NOTICE. \$\endgroup\$ – primo Sep 11 '15 at 16:52
6
\$\begingroup\$

QBasic / Javascript, 153 134 bytes

UPDATE: Saw that the text could be de-duplicated:

a$="This program wasn't written in "
b$=", it was built for "
PRINT(a$+"JS"+b$+"QB!")
'';function PRINT(){alert(a$+"QB"+b$+"JS!");}

First post! Anyway, my code is:

PRINT ("This program wasn't written in JS, it was built for QB!")
'';function PRINT(){alert("This program wasn't written in QB, it was built for JS!");}

In QBasic, it prints the first line and doesn't execute the second line because it's believed to be a comment (thank you '). In JS, it calls the function PRINT, which is defined on the second line.

\$\endgroup\$
6
\$\begingroup\$

Emotinomicon/Python 2, 168 bytes

#😭!2 nohtyP rof tliub saw ti ,nocimonitomE ni nettirw t'nsaw margorp sihT😲⏪⏬⏩
print"This program wasn't written in Python 2, it was built for Emotinomicon!"

or with more languages:

Emotinomicon/Python 2/><>, 267 bytes

v=0
 #😭!2 nohtyP rof tliub saw ti ,nocimonitomE ni nettirw t'nsaw margorp sihT😲⏪⏬⏩
for _ in[0]:print"This program wasn't written in Python 2, it was built for ><>!"
"""
"
>v
v>"!nocimonitomE rof tliub saw ti ,><> ni nettirw t'nsaw margorp sihT"
>l?!;o
"""

but I'm bored so let's add another language:

Emotinomicon/Python 2/><>/Gol><>, 358 bytes

v=0
 #😭!2 nohtyP rof tliub saw ti ,nocimonitomE ni nettirw t'nsaw margorp sihT😲⏪⏬⏩
for _ in[0]:print"This program wasn't written in Python 2, it was built for ><>!"
"""
`
"
?
>v
v>"!><>loG rof tliub saw ti ,><> ni nettirw t'nsaw margorp sihT"
>l?!;o
"
>!v~~~~~"!nocimonitomE rof tliub saw ti ,><>loG ni nettirw t'nsaw margorp sihT"0q
  >l?!;o
"""
\$\endgroup\$
6
\$\begingroup\$

Ruby/Python 3, 127 122 114 109 bytes

a=["Python","Ruby"];b=(0 and 1);print("This program wasn't written in "+a[b]+", it was built for "+a[~b]+"!")

Explanation: Ruby evaluates 0 to true whereas Python evaluates it to false. The b=(0 and 1) determines whether 0 is truthy, so it represents the array index of the language it's being called from. Python had to come first because it can act oddly when the statement after the and evaluates to false. Also, that link says that it only works in older Python versions but I tried it in Python 3 and it worked fine.

Thanks kirbyfan64sos for removing 5 13 bytes!

Edit: Turns out 0 and 1 instead of 0 and 1 or 0 will also determine whether 1 is truthy in both languages.

\$\endgroup\$
  • 2
    \$\begingroup\$ Nice! You can shave a 5 bytes off by changing a[(b+1)%2] to a[~b]. \$\endgroup\$ – kirbyfan64sos Sep 5 '15 at 23:43
  • \$\begingroup\$ @kirbyfan64sos thanks, implemented! I never really knew about that operator before \$\endgroup\$ – Piccolo Sep 6 '15 at 17:20
  • 1
    \$\begingroup\$ It's the bitwise complement: 0 becomes -1 (which is the last element of a two-element array, 1), and 1 becomes -2 (which is the first element of a two-element array, 0). \$\endgroup\$ – kirbyfan64sos Sep 6 '15 at 17:20
  • \$\begingroup\$ One more thing: is it possible to remove the spaces around the plus signs? \$\endgroup\$ – kirbyfan64sos Sep 6 '15 at 17:22
  • \$\begingroup\$ @kirbyfan64sos yes! I'm kinda new to this whole code golfing thing, thanks \$\endgroup\$ – Piccolo Sep 6 '15 at 17:24
5
\$\begingroup\$

Python/Pip, 103 bytes

print(#x)O
"This program wasn't written in "#xO"Pip"Y
"Python"#xO
", it was built for "  "Pip!")
#xy.'!

GitHub repository for Pip

The main difficulty with Python and Pip is that they use completely different syntax for output (print vs O/P), for string concatenation (+ vs .), and for assignment (= vs :). At least they have the same syntax for defining strings! This is how Python interprets the program, with comments moved for clarity:

print(                             #x)O
"This program wasn't written in "  #xO"Pip"Y
"Python"                           #xO
", it was built for "  "Pip!")     
                                   #xy.'!

Literal strings in Python that are separated only by whitespace are concatenated.

Now here's how the program looks to the Pip interpreter:

p r i n t                           No-ops (all lowercase letters are variables)
(#x)                                Another no-op (# is the unary length operator)
O"This program wasn't written in "  Output without newline
#x                                  No-op
O"Pip"                              Output
Y"Python"                           The yank operator Y assigns its operand to y
#x                                  No-op
O", it was built for "              "Pip!") is a comment since it comes after two spaces
#x                                  No-op
y.'!                                Concatenate ! to the end of y and print (implicit)
\$\endgroup\$
5
\$\begingroup\$

Haskell / C - 225 219 bytes

Probably not optimized very well.

Haskell

int /* x = x -- */ printf(const char*,...); /*
main = putStrLn "This program wasn't written in C, it was built for Haskell!"
-- */ int main () { printf("This program wasn't written in Haskell, it was built for C!"); }

C

int /* x = x -- */ printf(const char*,...); /*
main = putStrLn "This program wasn't written in C, it was built for Haskell!"
-- */ int main () { printf("This program wasn't written in Haskell, it was built for C!"); }
\$\endgroup\$
  • \$\begingroup\$ FYI I could cut some whitespace to save bytes, but I don't feel like that'd improve the answer by much. \$\endgroup\$ – Cubic Sep 7 '15 at 5:30
  • \$\begingroup\$ Got it down to 173 \$\endgroup\$ – Esolanging Fruit Apr 20 '18 at 7:08
  • \$\begingroup\$ Aren't the Haskell/C strings mixed up? That should be really easy to fix. \$\endgroup\$ – dfeuer Mar 4 at 21:20
  • \$\begingroup\$ @EsolangingFruit this skips the declaration of the output function, which I wanted to include so it compiles without warnings. Could save a couple bytes by using puts instead of printf though. \$\endgroup\$ – Cubic May 17 at 10:42
5
\$\begingroup\$

Haskell/Python 198 185 Bytes

Haskell

pass#b=b
pass##b=pass++b
p=print#putStrLn where print=p
main=p("This program wasn't written for "##(
 "Python"#"Haskell")##
 ", it was built for "##(
 "Haskell"#"Python")##
 "!")

Python

pass#b=b
pass##b=pass++b
p=print#putStrLn where print=p
main=p("This program wasn't written for "##(
 "Python"#"Haskell")##
 ", it was built for "##(
 "Haskell"#"Python")##
 "!")

Not actually sure if it works with all Pythons. Should work with python 3 at least.

If quotes in the output were valid, we could remove the third line and just use print in main (it'd print quotes around the string in haskell) - I'm assuming this is not valid here.

Explanation: The first 2 lines are no-ops in python (they just consist of pass), in Haskell they define 'select second' and 'concatenate' and concatenate operators respectively. The next line defines a 'variable' both in python and in haskell; In python it's pointing to print, in haskell it's defined as putStrLn (the where part shadows print, without it we would get type instantiation errors because of print there). The part after that is just abusing the fact that consecutive string literals in Python are concatenated like in C, in haskell we use the concatenation operator instead. We swap out "Python" and "Haskell" using our selection operators.

In python, the assignment to main is useless but valid. In Haskell, it's required because we need a main :: IO ().

\$\endgroup\$
5
\$\begingroup\$

Ruby 2.1.5/JavaScript, 189

i
=begin
=9;n=console.log;end='';y
=end
//=~'';def n(x);puts x;end
n("This program wasn't written in "+(f=['JavaScript','Ruby'])[b='k'.match(/[^\W]/i)?0:1]+", it was built for "+f[1-b]+"!")

This does some simple polyglot manipulation to make n a function that prints to stdout. That's the only polyglot trick. The real trick is that Ruby has a bug in the Regexp matcher wherein "k" and "s" do not match /[^\W]/i due to case-folding. It's in the official documentation, too.

Anyway, to Ruby, this looks like:

i       # a pointless variable declaration
=begin
  This is a block comment
=end
//=~''; # just a pointless regex evaluation

# declare a method `n` which puts to stdout
def n(x)
  puts x
end

# call n.  b will equal 1 since this erroneously fails to match.
n("This program wasn't written in "+(f=['JavaScript','Ruby'])[b='k'.match(/[^\W]/i)?0:1]+", it was built for "+f[1-b]+"!")

And to JavaScript, it looks like:

i=begin=9;  // pointless assignment of i and begin to 9
n=console.log; // set up `n` as a function to log to stdout

// more pointless assignments....
end='';
y=end

// comments
//=~'';def n(x);puts x;end

// call n.  b will be 0 because JS does not share Ruby's bug.
n("This program wasn't written in "+(f=['JavaScript','Ruby'])[b='k'.match(/[^\W]/i)?0:1]+", it was built for "+f[1-b]+"!")
\$\endgroup\$
  • \$\begingroup\$ I realize that it'd be shorter to use the truthiness of 0 in both languages, but I've been looking for a way to exploit this bug for months. \$\endgroup\$ – Not that Charles Sep 3 '15 at 19:39
  • \$\begingroup\$ The polyglottishness was stolen outright from a younger me \$\endgroup\$ – Not that Charles Sep 3 '15 at 19:48
  • \$\begingroup\$ That's a great bug! Seems to be fixed in the latest Ruby, too, so you could use it to distinguish between 2.1 and 2.2. \$\endgroup\$ – histocrat Sep 4 '15 at 1:58
  • \$\begingroup\$ What version of ruby is this meant to run in? I just get undefined local variable or method 'i' for main:Object (NameError) when I try to run it on 2.2.3p173 \$\endgroup\$ – Shelvacu Oct 31 '15 at 0:44
  • \$\begingroup\$ @Shel v2.1.5. It should also work in 2.0.0 and maybe even 1.8.7 \$\endgroup\$ – Not that Charles Nov 1 '15 at 3:46
5
\$\begingroup\$

Haskell / Literate Haskell (195 bytes)

I hope this isn't cheaty, but I fully intended it to be cheeky!

main = putStrLn "This program wasn't written in Haskell, it was built for Literate Haskell!"
{-

> main = putStrLn "This program wasn't written in Literate Haskell, it was built for Haskell!"

-}
\$\endgroup\$
  • 2
    \$\begingroup\$ Can you remove the spaces around = and putStrLn? \$\endgroup\$ – Esolanging Fruit Nov 19 '17 at 3:28
5
\$\begingroup\$

Hugs 98 Haskell/GHC Haskell, 203 bytes

Edit: Please also see this version, which is more interesting, and now shorter as well!

This takes advantage of an accidental change in the strictness of foldl' in the base library that came with GHC 7.10. Said change was noted several years ago, but has not been reverted. The "version names" I've used are a bit bogus, but they mirror the ones on TIO. It would be trivial to use something different.

import Control.Exception
import Data.List
p#q=putStrLn$"This program wasn't written in Haskell"++p++", it was built for Haskell"++q++"!"
main=handle(\ErrorCall{}->""#"98")$foldl'(!)(error"")[1]
_!_="98"#""

Try it online (GHC)

Try it online (Hugs)

\$\endgroup\$
  • 1
    \$\begingroup\$ You can shorten (ErrorCall _) to ErrorCall{}. \$\endgroup\$ – Ørjan Johansen Mar 11 at 22:14
  • \$\begingroup\$ @ØrjanJohansen, heh, I made a similar suggestion to someone else recently! Thanks. \$\endgroup\$ – dfeuer Mar 11 at 22:33
  • 1
    \$\begingroup\$ 201 bytes \$\endgroup\$ – Ørjan Johansen Mar 11 at 23:38
4
\$\begingroup\$

Brainfuck/Bash 4.3, 849 848 843 bytes

#-[--->+<]>-.[---->+++++<]>-.+.++++++++++.+[---->+<]>+++.[-->+++++++<]>.++.---.--------.+++++++++++.+++[->+++<]>++.++++++++++++.[->+++++<]>-.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.-----.[++>---<]>++.[->+++<]>-.[---->+<]>+++.--[->++++<]>-.-----.---------.+++++++++++..+++[->+++<]>.+++++++++.-[->+++++<]>-.-[--->++<]>-.+++++.-[->+++++<]>-.+[->++<]>.---[----->+<]>-.+++[->+++<]>++.++++++++.+++++.--------.-[--->+<]>--.+[->+++<]>+.++++++++.+++[----->++<]>.------------.-[--->++<]>-.+++++++++++.[---->+<]>+++.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.+[---->+<]>+++.[->+++<]>++.[--->+<]>-.------------.+++.++++++++.[---->+<]>+++.++[->+++<]>.+++++++++.+++.[-->+++++<]>+++.+[->++<]>.[-->+++<]>--.--[--->+<]>--.-----------.--[--->+<]>--.++[-->+++<]>+.------.+++++.[--->++<]>
echo -e "This program wasn't written in Bash 4.3, it was built for Brainfuck!"
\$\endgroup\$
  • \$\begingroup\$ This doesn't have the ! at the end. All you have to do to fix this is change the ending >- on the Brainfuck line to >-.. \$\endgroup\$ – Kade Sep 3 '15 at 13:32
  • \$\begingroup\$ @Shebang nope. That point is hidden in the bash version :) \$\endgroup\$ – rpax Sep 3 '15 at 13:37
  • \$\begingroup\$ ..what? That's not what I said. You do not print an exclamation point when executed in Brainfuck, so this answer is not valid. \$\endgroup\$ – Kade Sep 3 '15 at 13:43
  • \$\begingroup\$ The ending . you mean is located in Bash 4.3 \$\endgroup\$ – rpax Sep 3 '15 at 13:44
  • \$\begingroup\$ @Shebang you were right. Instead of adding a ., removing the last - in the first line solved the problem. I forgot about the minus sign in echo -e. Thank you! \$\endgroup\$ – rpax Sep 3 '15 at 13:58
4
\$\begingroup\$

Python/Boo, 102 bytes

v=1//2
n=("Python","Boo");print"This program wasn't written in "+n[v]+", it was built for "+n[1-v]+"!"

Explanation: Boo's syntax is strongly based on Python's, but it uses // as a C-style comment, whereas Python uses it for integer division.

\$\endgroup\$
4
\$\begingroup\$

JavaScript/JavaScript ES6, 132 130 bytes

var v=[];v[0]=v[1]=" JavaScript";v[[].fill?0:1]+=" ES6";alert("This program wasn't written in"+v[0]+", it was built for"+v[1]+"!")
\$\endgroup\$
  • 1
    \$\begingroup\$ You can save 2 bytes by using [].fill or [].find instead of [].values \$\endgroup\$ – Patrick Roberts Sep 8 '15 at 20:20
  • \$\begingroup\$ And I just noticed you can save another byte by using +!![].fill instead of [].fill?0:1 \$\endgroup\$ – Patrick Roberts Sep 8 '15 at 20:27
  • \$\begingroup\$ @PatrickRoberts thanks! I didn't notice fill! But, are you sure about the +!![].fill? I make a few tests on online interpreters and firefox and I'm not getting the expected results. \$\endgroup\$ – frikinside Sep 9 '15 at 7:13
  • \$\begingroup\$ Well the idea is to cast the function to a boolean then a number which is either 0 or 1 based on whether the version is ES6 or not, so that was the idea but maybe it doesn't work in practice \$\endgroup\$ – Patrick Roberts Sep 9 '15 at 11:38
4
\$\begingroup\$

Java/Groovy, 190 186 184 181 bytes

class A{public static void main(String[]a){String Groovy=" Java",Java=" Groovy";System.out.print("This program wasn't written in$Java, it was built for$Groovy!".replace('$',' '));}}

Ungolfed:

class NotThatLanguage {
  public static void main(String[] args) {
    String Groovy=" Java", Java=" Groovy";
    System.out.print("This program wasn't written in$Java, it was built for$Groovy!".replace('$', ' '));
  }
}
\$\endgroup\$
4
\$\begingroup\$

Mathematica 9/Mathematica 10, 115 bytes

Print["This program wasn't written in",a=" Mathematica ",If[b=Now==Now,9,10],", it was built for",a,If[b,10,9],"!"]

A bit late to the party... In Mathematica 9, Now remains unevaluated, and therefore equals itself. In Mma 10, each evaluation has a slight time offset, causing the two Nows to be unequal.

\$\endgroup\$
  • \$\begingroup\$ You could replace the print function with ""<>{} with those strings as parameters to shave of a byte since Mathematica prints the evaluation implicitly. <> is shorthand for StringJoin. \$\endgroup\$ – Pavel Oct 26 '16 at 23:52
  • \$\begingroup\$ @Pavel The Mathematica REPL is not considered to be a full program. \$\endgroup\$ – LegionMammal978 Oct 27 '16 at 0:05
4
\$\begingroup\$

MATLAB / Octave, 118 116 Bytes

x=all(version-82);s={'Octave','MATLAB'};
fprintf('This code wasn''t written in %s, it was built for %s!',s{2-[x ~x]})

This works because version returns something like: 8.4.0.150421 (R2014b), in MATLAB, and 3.6.2 in Octave. version-82 will contain a zero if there is an R in the version name. all(version-82) gives true if there are only non-zero values, and false if one value is zero.

\$\endgroup\$
4
\$\begingroup\$

PowerShell 2/PowerShell 3, 144 118 Bytes

$p="PowerShell ";$a,$b=try{$d=[ordered]@{};3,2}catch{2,3}"This program wasn't written in $p$a, it was built for $p$b!"

Saved a bunch of bytes thanks to @Matt

There are probably other ways of doing this, but this is a simple one, and relatively short. The [ordered] keyword was only introduced with PowerShell v3 and later, which means that PowerShell v2 doesn't support it. A simple try/catch to set the appropriate variables, and we're off and running. (Note that the $d= is necessary to suppress setting $a to the hashtable and $b to an array when run on PowerShell 3.)

\$\endgroup\$
  • \$\begingroup\$ I would replace the try block with this instead $a,$b=try{$d=[Ordered]@{};3,2}catch{2,3} pretty sure that will work the same and is shorter all around \$\endgroup\$ – Matt Oct 27 '16 at 12:00
4
\$\begingroup\$

C++ (gcc) / R, 163 bytes

#include<cstdio>
#define cat(x)x
#define sprintf(a,b,c)int main(){printf(a,c,b);}
cat(sprintf("This program wasn't written in %s, it was built for %s!","R","C++"))

C++ (gcc) : Try it online!

R : Try it online!

# is the comment character in R, so using preprocessor's magic of C++ we can switch between the two languages

\$\endgroup\$
4
\$\begingroup\$

Haskell GHC/Hugs98, 199 bytes

I've already written a different program for these language variants, but I think this one is much more clever. And now, it's also shorter!

Thanks to @ASCII-only for suggesting putStr instead of putStrLn. Thanks to @ØrjanJohansen for suggesting id rather than a custom operator for a related answer, and then shedding a full 30 bytes by realizing the Num instance can be left empty.

instance Eq(a->b)where _==_=0<1
instance Show(a->b)
instance Num(a->b)
p#q=putStr$"This program wasn't written in Haskell"++p++", it was built for Haskell"++q++"!"
main|(0`id`)==1=""#"98"|0<1="98"#""

Try it online (GHC Haskell)

Try it online (Hugs98 Haskell)

Explanation

Hugs 98 used a "relaxed" interpretation of operator sections, where (x!) meant (!) x. In even vaguely recent times, GHC has only used that relaxed interpretation when a certain language extension is enabled. The rest of the time, (x!) means \y -> (!) x y. The latter (more strictly standards-compliant) interpretation can cause the type constraints on (x`id`) to be stronger. In particular, it requires id to be a function of (at least) two arguments.

Haskell has a mechanism for defaulting ambiguous types under certain narrow conditions. The defaulting mechanism is just sensitive enough to the imposed constraints that we can detect the difference in operator section interpretation.

Open questions

  • Is it possible to cut the code size down? I'm not terribly happy with the way I actually put the strings together.
  • Is it possible to use Haskell's special rules for pattern matching on numeric literals without increasing the code size? That would make it even golfier, IMO.
\$\endgroup\$
  • \$\begingroup\$ Wait, why not putStr \$\endgroup\$ – ASCII-only Mar 11 at 9:45
  • \$\begingroup\$ @ASCII-only, fixed. \$\endgroup\$ – dfeuer Mar 11 at 22:12
  • 2
    \$\begingroup\$ This is too lazy to ever evaluate a function number literal, so just instance Num(a->b) will do. \$\endgroup\$ – Ørjan Johansen Mar 12 at 0:20
3
\$\begingroup\$

PHP/Javascript 178 chars

/*<?php echo "This program wasn't written in PHP, it was built for JavaScript!*"."/";exit;?>*/console.log("/*This program wasn't written in JavaScript, it was built for PHP!*/");

This is not perfect due to the Fact it is in this Format: /*{Message}*/.

It abuses the Comments from Javascript and the exit; function from PHP, which also causes the stupid Format.

\$\endgroup\$
3
\$\begingroup\$

PHP/Javascript(ES6), 191 bytes

This one is quite obvious for some people. And I think it is bigger than the existing PHP/JS answer.

$e=($j="\0"=='\0')?[a=>console.log(a.join(''))][0]:function($a){echo(join('',$a));};$L=['PHP','Javascript'];$e(["This program wasn't written in ",$L[+$j],', it was built for ',$L[+!$j],'!']);

You can try it on:

I believe there's a bit more to chop off.

\$\endgroup\$
3
\$\begingroup\$

Selectors Level 4/Selectors Level 3, 148 chars

:has(*){--a:4;--b:3}*{--a:3;--b:4;content:"This program wasn't written in Selectors Level "var(--a)", it was built for Selectors Level "var(--b)"!"}

It works like this:

  • I assume a HTML document with a root element (<html>) and some child (<body>). Those should be generated automatically by the HTML parser, even if they aren't in the source code.
  • * will match <html>
  • I assume support of CSS Custom Properties for Cascading Variables Module Level 1. This will create the variables --a and --b.
  • In Selectors Level 3, :has(*) in an invalid selector, so it's ignored silently.
  • In Selectors Level 4, <html> matches :has(*), which has more specificity than *. This will modify the variables.
  • I assume support of CSS3 Generated and Replaced Content Module. The content property will replace the contents of <html> with the desired string, which uses var() to read the variables.

I think it should work, but I don't have any implementation to test it.

Thankfully, the name of the spec is only "Selectors Level X" instead of "CSS3 Selectors and Foo for Bar Module Level X".

\$\endgroup\$
  • 1
    \$\begingroup\$ Only Opera 12 supports content for real elements. Not sure, but probably you need to use pseudoelement. What does specification sais about it? And at the moment only Firefox supports css variables. \$\endgroup\$ – Qwertiy Sep 4 '15 at 13:55
  • \$\begingroup\$ Just a little note: Selectors Level 4 does not imply support for CSS Custom Properties for Cascading Variables Module Level 1 or CSS3 Generated and Replaced Content Module. \$\endgroup\$ – Toothbrush Sep 4 '15 at 20:27
  • \$\begingroup\$ @Qwertiy But html:after is longer than * (I would have to target html explicitly to avoid displaying the string twice: for html and body) \$\endgroup\$ – Oriol Sep 4 '15 at 21:15
3
\$\begingroup\$

Perl 5 / Perl 6, 113 bytes

$X=5;$Y=6;if ("a".chars>0) {$X++;$Y--}print "This program wasn't written in Perl $X, it was built for Perl $Y!\n"

This proved to be harder than anticipated.

How it works? In perl 6 the "a".chars gives a result of 1.
But in Perl 5 the string "achars" is compared against a number, which results in false.

(** shakes finger at perl 6 for making it harder to golf **)

\$\endgroup\$
  • \$\begingroup\$ This doesn't work in Perl 6 unless you add a no strict at the beginning \$\endgroup\$ – Brad Gilbert b2gills Dec 12 '15 at 17:23
3
\$\begingroup\$

Perl 5 / Perl 6

perl -e '$x= ~ -2; printf "This program wasn\x27t written in perl\%d, it was built for perl\%d", 4+abs($x), 7-abs($x);'
\$\endgroup\$
  • \$\begingroup\$ Explanation, please? \$\endgroup\$ – kirbyfan64sos Sep 10 '15 at 16:43
  • \$\begingroup\$ ~ is complement in 5; string coercion in 6. \$\endgroup\$ – user52889 Sep 10 '15 at 17:01
  • \$\begingroup\$ I was going to use $/=5;$_=6;#`(␤$/++;$_--;#)␤print "This program wasn't written in Perl $_, it was built for Perl $/!\n" \$\endgroup\$ – Brad Gilbert b2gills Dec 12 '15 at 17:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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