192
\$\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\$
8
  • 3
    \$\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
  • 2
    \$\begingroup\$ Added it, it feels paradoxical but fits to your rules. \$\endgroup\$
    – Zaibis
    Sep 3 '15 at 14:48
  • 3
    \$\begingroup\$ No one's doing a Whitespace/Python polyglot? \$\endgroup\$ Sep 4 '15 at 15:22
  • 1
    \$\begingroup\$ nevermind. Saw the 23 implementation \$\endgroup\$ Sep 4 '15 at 15:26
  • 1
    \$\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

119 Answers 119

4
\$\begingroup\$

Vyxal V, 53 bytes

`λ« ƛ¾ wṠǒ't «ḭ in %, it λ¨ €₇ λ⟑ %!`‛₴ŀ:‛ V+"w1→iR∑%

Try it Online!

`...`                            # String with % in place of the language names
     ‛₴ŀ              # String 'Vyxal'
        :             # Duplicate
         ‛ V+         # Append ' V' to one copy
             "        # Pair with itself
              w       # Wrap in a list
               1→iR   # If flagless, this stores 1 to the variable iR.
                      # If the V flag, this stores 1 to the variable i, and swaps the two
                   ∑  # Unwrap
                    % # Format, replacing the %s

-11 thanks to Aaron Miller.

\$\endgroup\$
3
  • \$\begingroup\$ Now that deserves a +1. You absolute madlad. You’ve inspired me to do something similar. \$\endgroup\$ Jul 24 at 16:04
  • 1
    \$\begingroup\$ 53 bytes \$\endgroup\$ Jul 27 at 15:13
  • \$\begingroup\$ @AaronMiller Oh that is very nice. \$\endgroup\$
    – emanresu A
    Jul 27 at 19:25
4
\$\begingroup\$

Lua/Python, 150 bytes

Code:

print(1^2==1 and "This program wasn't written in Lua, it was built for Python!" or "This program wasn't written in Python, it was built for Lua!")

Explanation

This program makes use of three things:

  1. Python and Lua both print output with the 'print()' function.
  2. Python interprets the '^' operator as bitwise-xor, while Lua interprets it as an exponent operator.
  3. This was the tricky part. Python and Lua have completely different syntaxes and keywords for conditionals, so I had to find a syntax that means the same thing in both languages. I was able to do this when I stumbled upon the fact that ' and or ' will return the '' if '' is True, and '' if it is False.

When I first started this challenge, I attempted to make use of the fact that Python zero-indexes lists, while Lua one-indexes them. However, this failed because Lua uses curly brackets instead of Python's straight brackets. At first I thought it might work since curly brackets denote sets in Python, but Python doesn't allow you to access a set element the same way you access a list element since Python sets are by definition 'unordered,' so I gave up that idea and looked for alternatives until I remembered that the '^' operator doesn't mean exponentiation in Python, and I devised a solution based on the fact that the '^' operator means exponentiation in Lua, but not Python.

Try it Online! (Python)

Try it Online! (Lua)

\$\endgroup\$
6
  • \$\begingroup\$ It seems that print with parens does work in Python 2… \$\endgroup\$
    – xigoi
    Jul 27 at 23:11
  • \$\begingroup\$ Also you can remove the " 3" since you have only one version of Python. \$\endgroup\$
    – xigoi
    Jul 27 at 23:12
  • \$\begingroup\$ Okay thanks. I just edited my post. I thought that Python 2 only had a print statement. whoops. \$\endgroup\$ Jul 28 at 16:54
  • \$\begingroup\$ Also, if you were wondering, I couldn't shave bytes easily by concatenating strings. Python uses the '+' operator, and Lua uses '..'. If you know a way to get around this, let me know and I'll try to golf the code to a smaller size. \$\endgroup\$ Jul 28 at 16:58
  • 2
    \$\begingroup\$ Python 2 only has a print statement, that's right, but it can be called like this because, as usual, you can wrap anything in parens. \$\endgroup\$
    – xigoi
    Jul 28 at 18:14
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\$

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\$
1
  • \$\begingroup\$ This doesn't work in Perl 6 unless you add a no strict at the beginning \$\endgroup\$ 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\$
3
  • \$\begingroup\$ Explanation, please? \$\endgroup\$ 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\$ Dec 12 '15 at 17:16
3
\$\begingroup\$

Perl5 / JavaScript

y= 1, split = function(){return ''; " =; #"}
print ( "This program wasn't written for", split( //, " Perl, it was built for JavaScript!") );
y), "\bJavascript, it was built for Perl!");
x=split();
\$\endgroup\$
3
\$\begingroup\$

Commodore 64 Basic/QBasic, 169

In order to get the capitalization right, you'll need to switch your Commodore 64 to character set 2 by pressing <SHIFT> + <C=>.

1 c$ = "QBasic": d$ = "Commodore 64 Basic"
2 if(fre(0) < 0) then e$ = c$:c$ = d$:d$ = e$
3 print "This program wasn't written in "; c$; ", it was built for "; d$; "!"

In Microsoft dialects of Basic, the "fre()" function returns the available free space. Now, QBasic can run on surprisingly low-memory IBM compatibles, so you can't reliably tell QBasic and Commodore Basic apart just by the amount of free space. However, the Commodore Basic version returns a signed 16-bit integer where the QBasic version returns a 32-bit one -- and since the Commodore 64 has more than 32767 bytes free with just a small program, while QBasic, as a real-mode program, will never see more than 1048576 bytes, "fre(0)" will always return a negative number on a C64 and a positive number under QBasic.

Commodore Basic's 80-character-per-line limit and QBasic's autoformatter interact in annoying ways here. For example, I found a neat trick involving an if-then-else statement (invalid in Commodore Basic, but an "end" statement keeps the Commodore interpreter from encountering the invalid bits) -- except that the resulting line is 86 characters long after QBasic's autoformatter gets through adding whitespace. Likewise, line 1 can't be combined with line 2: the result would be 88 characters long after autoformatting.

\$\endgroup\$
4
  • \$\begingroup\$ Why does QBasic autoformatting matter? \$\endgroup\$ Mar 7 '16 at 0:42
  • \$\begingroup\$ @CatsAreFluffy, QBasic has a combined editor/interpreter. If you type in or load a program with what it considers improper whitespace, it will insert the whitespace for you. \$\endgroup\$
    – Mark
    Mar 7 '16 at 19:00
  • \$\begingroup\$ So? If you paste an improperly formatted program in, it'll be autoformatted. I just don't get why the pasted-in program has to be formatted properly. If people had to care about whitespace added by the IDE, I'd have to fix every single one of my answers. (Well actually, I think 3 of them are fine, but why is ths so long) \$\endgroup\$ Mar 7 '16 at 19:08
  • \$\begingroup\$ I'm pretty sure there's a thing called QB64 which allows disabling autoformatting. \$\endgroup\$ Apr 2 '16 at 19:56
3
\$\begingroup\$

Scala/Groovy, 128 bytes

Adapting my Java/Groovy snippet for Scala instead lets us get rid of a lot of Java boilerplate:

def Scala=" Groovy"
def Groovy=" Scala"
print("This program wasn't written in$Scala, it was built for$Groovy!".replace('$',' '))
\$\endgroup\$
1
  • \$\begingroup\$ Worth pointing out that this isn't scala "proper", but Scala script. A full scala program does still need a main entry point. \$\endgroup\$
    – Cubic
    Nov 1 '15 at 12:35
3
\$\begingroup\$

jq / Python 3, 151

"\("; print('This program wasn\u0027t written in Python 3, it was built for jq!')#" | "This program wasn't written in jq, it was built for Python 3!")"

The problem gets a little bit complicated when one of the languages does not have a comment syntax.

Run with jq -n -r or with python3.

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

JavaScript / JavaScript ES6, 110 bytes

"This program wasn't written in "+((b=[a="JavaScript",c=a+" ES6"].keys)?c:a)+", it was built for "+(b?a:c)+"!"

Checks for the existence of .keys. Most browsers these days are ES6 so I recommend installing a separate engine such as Rhino if you really want to test this.

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

CoffeeScript+CJam

Uses CoffeeScript's ### and CJam's e#

e###
"This program wasn't written in CJam, it was built for CoffeeScript!"
e### ###
e### alert "This program wasn't written in CoffeeScript, it was built for CJam!"

How CJam sees it

e# comment
push "This program wasn't written in CJam, it was built for CoffeeScript!"
e# comment
e# comment

How Coffee sees it:

e
###
comment
###
###
comment
###
alert("This program wasn't written in CoffeeScript, it was built for CJam!")
\$\endgroup\$
3
\$\begingroup\$

Javascript ES6, ES5 131 127 bytes

I just thought I post this for fun

"This program wasn't written in "+((c=eval("try{let a=0}catch(e){1}"))?"ES5":"ES6")+", it was built for "+(c?"ES6":"ES5")+"!"

The main part of the code is this:

try{d.join``;0}catch(e){1}

If the version of javascript is ES5, this returns 1, because d.join`` throws an error.

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

Crystal / Ruby, 117 bytes

c="Crystal";r="Ruby";x='a'!="a";puts "This program wasn't written in "+(x ?c: r)+", it was built for "+(x ?r: c)+"!"

Crystal is heavily inspired by Ruby, so not much trickery is needed here except a way to detect which language is being used. This snippet abuses a key difference in both languages: Crystal has a character type (Char), while Ruby only has a String.

In Crystal, 'a' is a character literal, while "a" is a string literal. In Ruby, both are string literals. The code tests if 'a'=="a" (true in Ruby, false in Crystal) then uses that to decide whether to print Crystal or Ruby.

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

JavaScript / Python3, 119 bytes

i=1//2
d=['print','console.log']
s=['python','js']
eval(d[i])('this program is not '+s[i]+', it was built for '+s[1-i])

Tested on Node.js v6.x and Python 3.5.1

The trick was to use Python's "floor division" operator which is the same as JavaScript's line comment //. This is how we swap 0 and 1 for i depending on the language.

This won't work on python2 because print was not a function until python3 and therefore cannot be evaluated using eval. It should work for almost any JavaScript VM.

Edit

Golfed 7 bytes by removing j variable and using s[1-i] instead of s[j].

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You could remove the j= line and use eval(d[i])('this program is not '+s[i]+', it was built for '+s[1-i]), for a saving of 7 bytes :) \$\endgroup\$ Nov 10 '16 at 17:38
  • \$\begingroup\$ @ETHproductions Thanks! That is clever! \$\endgroup\$
    – styfle
    Nov 10 '16 at 19:15
3
\$\begingroup\$

Ruby/Crystal, 149 140 bytes

v = 1e10.class == Float ? ["Ruby", "Crystal"] : ["Crystal", "Ruby"]
puts "This program wasn't written in #{v[0]}, it was built for #{v[1]}!"

Crystal is a language similar to Ruby, but it is compiled. In Crystal, the type of the literal 1e10 is Float64, while in Ruby it is Float. Probably can be golfed some.

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

Common Lisp / C, 208 156 150 119 bytes

;main(){puts(
//(format't"~A~2*~A~2@*~AC!"
"This program wasn't written in ""C"", it was built for ""Common Lisp""!");}

Try it online for C

Try it online for Common Lisp

-52 bytes thanks to @ceilingcat!

-37 bytes thanks to @ASCII-only and his excellent mastering of CL format function

\$\endgroup\$
11
  • \$\begingroup\$ Thanks a lot @ceilingcat, I did'nt know that puts could be used without include! \$\endgroup\$
    – Renzo
    Aug 22 '17 at 13:26
  • \$\begingroup\$ You appear to have an extra slash in the codeblock \$\endgroup\$
    – ASCII-only
    Mar 11 '19 at 3:36
  • \$\begingroup\$ :( smart way is 158 \$\endgroup\$
    – ASCII-only
    Mar 11 '19 at 3:41
  • \$\begingroup\$ 150 \$\endgroup\$
    – ASCII-only
    Mar 11 '19 at 3:52
  • \$\begingroup\$ Wonder if there's an easier way to concatenate strings, tried format but that doesn't seem to work too well (actually... 147) \$\endgroup\$
    – ASCII-only
    Mar 11 '19 at 8:42
3
\$\begingroup\$

x86_64/i386 machine code (with libc call), 91 bytes

One last machine code one, this time with actual machine code (and golfed assembly for the lulz). xx xx xx xx represents an unlinked placeholder, to main+23 (printf_str) and printf, respectively.

bf xx xx xx xx 8d 77 38  8d 57 3f 56 52 57 e8 xx
xx xx xx 5f 5a 5e c3 54  68 69 73 20 70 72 6f 67
72 61 6d 20 77 61 73 6e  27 74 20 77 72 69 74 74
65 6e 20 69 6e 20 25 73  2c 20 69 74 20 77 61 73
20 62 75 69 6c 74 20 66  6f 72 20 25 73 21 00 78
38 36 5f 36 34 00 69 33  38 36 00

x86_64: Try it online!

i386: Try it online!

What? You didn't expect me to not golf the demo, did you? 😏

Explanation

It is pretty simple. It abuses the fact that x86_64 and i386 have completely different calling conventions.

x86_64 (on Unix) passes (most) arguments in registers, starting with rdi, rsi, and rdx. It ignores the stack unless you run out of registers. This is called the System V calling convention.

i386 (on Unix and usually on Windows) passes all arguments on the stack in right to left (i.e. backwards from C) order. It ignores the registers. This is called the cdecl calling convention.

So I set up the x86_64 message in the registers, and the i386 message on the stack (with the arguments rearranged), then call printf. It's that simple.

Ungolfed assembly (substitute registers starting with r with e for i386):

        .intel_syntax noprefix
        .globl main
main:
        # First, set up a System V call for x86_64 in the registers.
        # We assume the program is low enough in memory and that PIC is off.
        #     printf(printf_str, "x86_64", "i386");
        mov     edi, offset printf_str
        lea     esi, [rdi + 56] # x86_64_str
        lea     edx, [rdi + 64] # i386_str
        # And then we set up a cdecl call for i386, but swap the arguments.
        # Since the arguments are already in registers, we can just push them.
        #     printf(printf_str, "i386", "x86_64");
        push    rsi # x86_64_str
        push    rdx # i386_str
        push    rdi # printf_str
        # Call printf, using each architecture's calling convention
        call    printf
        # Clean up the stack and return. We can't add to rsp, as the offsets
        # would be different on i386.
        pop     rdi
        pop     rdx
        pop     rsi
        ret
printf_str:
        .asciz "This program wasn't written in %s, it was built for %s!"
x86_64_str:
        .asciz "x86_64"
i386_str:
        .asciz "i386"
\$\endgroup\$
3
\$\begingroup\$

Assembly (MIPS, SPIM)/Assembly (GCC, MIPS Linux O32), 319 313 309 305 270 256 255 241 233 bytes

.globl main
main:la $5,p+9
lh $3,-7($5)
li $6,54
jal w
sub $5,5
li $6,5
jal w
xor $3,5
w:move $2,$3
syscall
jr $ra
.data
p:.word 0xf0fa4,0x5350494d
.ascii"!This program wasn't written in "
.word 0x4d495053
.ascii", it was built for "

Try it online!

Since it reuses argc, it must be called with no arguments. This is implied given that "neither program should take any input from the user.".

Outputs This program wasn't written in SPIM, it was built for MIPS! on SPIM (on a little endian machine).

Outputs This program wasn't written in MIPS, it was built for SPIM! on a real MIPS64 machine from the GCC Compiler Farm (specifically gcc22).

Explanation

Two words: Endian memes.

MIPS is big endian, while SPIM is little endian. This is perfect for us.

The first magic number is a "hybrid" encoding of the sys_write syscall. We store the SPIM syscall number in the most significant 16 bits, and the Linux syscall number in the least significant 16 bits.

We then do a halfword load on the address + 2.

On big endian, this would load the least significant bytes, while on little endian, it would load the most significant bytes. That is why you never cast pointers in C if you want your code to be portable. 😏

This is actually what we want: we will load the Linux syscall on big endian, and the SPIM syscall on little endian.

This is also used to obtain the sys_exit syscall number.

On SPIM, the syscall for sys_write is 15, while the syscall for sys_exit is 10.
On Linux, the syscall for sys_write is 4004, while the syscall for sys_exit is 4001.

15 XOR 10 is 4004 XOR 4001 is 5, so sys_write XOR 5 is sys_exit, quick maffs! 🤓

Therefore, to magically convert both the SPIM and MIPS syscalls from sys_write to sys_exit, we can simply XOR by 5!

The second two magic numbers are "SPIM" and "MIPS" in big endian packed ASCII, respectively. These are inline with the strings.

"SPIM" being simply "MIPS" backwards means that it will be reversed on little endian. On MIPS, this will be "SPIM" and "MIPS", respectively, while on SPIM, it will be "MIPS" and "SPIM", respectively.

The reason we store the strings backwards is because it is shorter, and more importantly, both GAS and SPIM will insert alignment bytes for .words if they are not 4 byte aligned which mangle our output.

By coincidence, the second half of the string ends one byte after a word boundary, and the first half of the string is one byte off from being aligned, so we just merge them together to remove all padding (and allowing us to merge the last ! into the next .ascii block).

| = word boundary, @ = padding, $ = EOS, W = .word
|   |   |   |   |   |   |   |   | W |   |   |   |   |   | W |
@This program wasn't written in MIPS, it was built for @SPIM!$
| W |   |   |   |   |   |   |   |   | W |   |   |   |   |   |
SPIM!This program wasn't written in MIPS, it was built for $

Note that while it looks like I could save space by writing 0xf0fa4 in base 10, I can't, because for some reason, SPIM doesn't like comma separated numbers unless they are in hex.

Ungolfed version (not compatible with SPIM because SPIM doesn't allow arithmetic in .word):

        .data
hybrid_syscall:
        # sys_write syscall. SPIM is the high 16 bits, MIPS Linux
        # is the low 16 bits.
        # By doing a halfword read, we can automatically read the
        # right syscall number thanks to endianness.
        .word (15 << 16) | 4004     # -9(string_1)

string_2: # "SPIM!"
        # "SPIM" in big endian packed ASCII.
        # SPIM will store this backwards as "MIPS".
        .word ('S' << 24) | ('P' << 16) | ('I' <<  8) | 'M'
        # This "!" also aligns string_1 so the "MIPS" is aligned.
        .ascii "!"

string_1: # "This program wasn't written in MIPS, it was built for "
        .ascii "This program wasn't written in "
        # "MIPS" in big endian packed ASCII.
        # SPIM will store this backwards as "SPIM".
        .word ('M' << 24) | ('I' << 16) | ('P' <<  8) | 'S'
        .ascii ", it was built for "

        .text
        .globl main
main:
        # Pointer to string_1
        la      $a1, string_1
        # Load the Linux sys_write syscall on big endian and the
        # SPIM sys_write syscall on little endian.
        # *(uint16_t *)(hybrid_syscall + 2) == sys_write
        # Uses a relative offset from string_1.
        lh      $v1, -9+2($a1)
        # strlen(string_1)
        li      $a2, 54
        # do_syscall(sys_write, string_1, strlen(string_1))
        jal     do_syscall

        # Pointer to string_2
        # In the golfed version, we subtract five from the last
        # pointer, because a1 is always returned unmodified.
        la      $a1, string_2
        # strlen(string_2)
        li      $a2, 5
        # do_syscall(sys_write, string_2, strlen(string_2))
        jal     do_syscall

        # Do an XOR to magically convert sys_write to sys_exit.
        xor     $v1, 5
        # FALLTHROUGH: do_syscall(sys_exit)

        # Runs a syscall.
        # C equivalent: syscall(v1, ...)
        # v1: syscall number
        # varargs: passed to syscall as-is
do_syscall:
        # Move the syscall number into v0.
        move    $v0, $v1
        # As long as our program is called with no arguments
        # which is implied by the rules, we can reuse argc to pass
        # 1 as the first argument, which corresponds to stdout.
        # li      $a0, 1

        # write(STDOUT_FILENO, string, length)
        # exit(1)
        syscall
        # Return
        jr      $ra
\$\endgroup\$
2
\$\begingroup\$

Brainfuck/Javascript 936 chars

/*[-]>[-]>++++[-<++++++++>]<>[-]>++++++[-<++++++++++>]<+++++>[-]>++++++++++[-<++++++++++>]<---<<<>>+++++++++++++++++++.>+++++++.+.++++++++++.<<.>>---.++.---.--------.+++++++++++.-----------------.++++++++++++.<<.>>++++++++++.----------------------.++++++++++++++++++.-----.<<+++++++.>>++++++.<<-------.>>+++.-----.---------.+++++++++++..---------------.+++++++++.<<.>>-----.+++++.<<.>------------------.>++++.-----------------.++++++++.+++++.--------.+++++++++++++++.------------------.++++++++.<<++++++++++++.------------.>>--.+++++++++++.<<.>>+++.----------------------.++++++++++++++++++.<<.>>-----------------.+++++++++++++++++++.------------.+++.++++++++.<<.>>--------------.+++++++++.+++.<<.>++++++++.>-----------------.+++++++++++++++++++++.---------------------.++++++++++++++++++.----------------.+++++++++++++++.---------.+++++++.++++.<<+*/console.log("This program wasn't written in Javascript, it was built for Brainfuck!");

This is just Brainfuck Code in a Comment Javascript will ignore, but Javacript Code that Brainfuck will ignore. So it is perfect. :D

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Outputs 'This program wasn't written in Brainfuck, it was built for Javascript!!' when executed in BF. Probably because you have an extra . in console.log. \$\endgroup\$
    – Blue
    Sep 3 '15 at 16:41
  • 1
    \$\begingroup\$ I think you can get around the issue @muddyfish mentioned by just removing the . before the */, which is a byte shorter anyhow. \$\endgroup\$ Sep 3 '15 at 17:16
  • \$\begingroup\$ I know, I was just waiting for the OP to do it themselves. \$\endgroup\$
    – Blue
    Sep 3 '15 at 17:26
  • \$\begingroup\$ fixed the little bug :D \$\endgroup\$
    – Sainan
    Sep 3 '15 at 17:35
  • 1
    \$\begingroup\$ You have another bug, the comma in your JS string will be executed, prompting for input. This probably isn't allowed, so you should use a hex escape sequence. \$\endgroup\$
    – mbomb007
    Sep 4 '15 at 17:29
2
\$\begingroup\$

MySQL (5) / Perl (5), 144 bytes

-- $_;print"This program wasn't written in Perl, it was built for MySQL!";
select"This program wasn't written in MySQL, it was built for Perl!";

h/t

\$\endgroup\$
2
\$\begingroup\$

Brainf***/Thue, 829 bytes

a::=~This program wasn't written in Thue, it was built for Brainf***!
::=
a++++++++[>+>++>+++>++++>+++++>++++++>+++++++>++++++++>+++++++++>++++++++++>+++++++++++>++++++++++++>+++++++++++++>++++++++++++++>+++++++++++++++>++++++++++++++++<<<<<<<<<<<<<<<<-]>>>>>>>>>>>----.++++>>.+.->+++.---<<<<<<<<<<.>>>>>>>>>>.++.---.+<-.+>++.--<<+.->>---.+++<<<<<<<<<<.>>>>>>>>>>>-.+<<<+.->>+++.-----.++<<<<<<<<<-.+>>>>>>>>>>----.++++<<<<<<<<<<<.>>>>>>>>>>>-.+<++.--<+.->>----.++++----.++++<<---.+++>--.++<<<<<<<<<<.>>>>>>>>>+.->--.++<<<<<<<<<<.>>>>++.-->>>>>>++.--<<+.->+.->--.++<--.++<<<<<<<<++.--++.--++.-->----.++++<<.>>>>>>>>>+.->>----.++++<<<<<<<<<<<.>>>>>>>>>>>-.+<<<+.->>+++.---<<<<<<<<<<.>>>>>>>>++.-->>>---.+++<<+.->----.++++>----.++++<<<<<<<<<<<.>>>>>>>>>--.++>-.+++.--<<<<<<<<<<.>>>>>>>----.++++>>.>>---.+++<<---.+++<<<<<<<<<+.-<<<<.
\$\endgroup\$
2
\$\begingroup\$

Python/Lisp 158 chars

""""(princ "This program wasn't written in Lisp, it was built for Python!")""";print 'This program wasn\'t written in Python, it was built for Lisp!';""" " """

\$\endgroup\$
2
\$\begingroup\$

BASH/JavaScript, 171 164 bytes

/* 2>&-;echo This program wasn\'t written in BASH, it was built for JavaScript\!;#*/console.log("This program wasn't written in JavaScript, it was built for BASH!")

First post to PPCG!

\$\endgroup\$
2
\$\begingroup\$

Shells/Emacs Lisp (157 bytes)

:; echo "This program was not written for shells, it was built for Emacs!"; exit
(message "This program was not written in Emacs, it was built for shells!")

: is a nop in both languages. ; is a comment in Emacs Lisp and a delimiter in many shells. :; is used as a startup hack for Emacs Lisp scripts, if you need to pass more than one argument to Emacs itself by the command line.

\$\endgroup\$
2
\$\begingroup\$

Fuzzy Octo Guacamole and Jolf, 112 bytes

(non-competing, FOG is newer than the challenge)

a++++"This program wasn\'t written in ""Jolf"", it was built for ""Fuzzy Octo Guacamole""!"//__ssss.Z_sssts''.jX

Prints This program wasn't written in Fuzzy Octo Guacamole, it was built for Jolf! in FOG, and This program wasn't written in Jolf, it was built for Fuzzy Octo Guacamole! in Jolf.

This was fun.

FOG side is complicated, because there is no command to swap the top 2 items.

FOG Explanation:

a++++"This program wasn\'t written in ""Jolf"", it was built for ""Fuzzy Octo Guacamole""!"//__ssss.Z_sssts''.j_;

The a adds the 2 top items, adding 0 and 0 and pushing the result, 0. Does nothing.

The + increment, so at the end the stack has [5].

The strings just push those to the stack.

The // does nothing but push '/' to the stack twice, but in Jolf it is a comment.

The __ pops the 2 '/'s we pushed, just removing them.

The ssss moves the top 4 strings, the parts that need rearranging, to the other stack. They are now in reverse order also.

The . switches stacks.

Z reverses the stack.

_ pops the '!', so we get it out of the way. It is set to the temp var.

Then we move the 'Fuzzy Octo Guacamole', the 'was built for', and the 'Jolf' to the other stack in that order. That is the 3 s.

t pushes the temp var, which is still the '!' and then the next s puts it on the other stack.

We have all the strings, but how to print?

We first push '', the empty string.

Then we switch stacks with ..

Then we use j. This is join. It pushes the current stack as a string with the top of the inactive stack as a separator.

This is equivalent to the python ''.join(stack).

Then the X pops and prints, and we are done!

Side note: The poor 5 is left on the stack, all by himself. ;_;

Jolf Explanation:

Much simpler.

Jolf is prefix, so the a gets the alert function ready.

The + all concatenate the strings, so they just get stuck together.

So this just prints as-is, no need to rearrange. And the // is a comment, and hides the FOG side code.


Thanks to @CᴏɴᴏʀO'Bʀɪᴇɴ for making Jolf, a wonderful language to use.

Aʟsᴏ, ғʀᴇᴇ ᴘʟᴜɢ ғᴏʀ sᴍᴀʟʟ ᴄᴀᴘs!!!

\$\endgroup\$
2
  • \$\begingroup\$ Does FOG's interpreter complain with non-ASCII? If so, you could use Ά in place of pairs of +s (so s/++/Ά/g). \$\endgroup\$ Apr 22 '16 at 3:30
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ no, but it will push the letters to the stack as strings. It ends up longer. \$\endgroup\$ Apr 22 '16 at 15:10
2
\$\begingroup\$

Python 2/C, 179 bytes

#if/*
"""*/1
main(){char*//"""
s="This program wasn't written in %s, it was built for %s!"
#if/*
"""*/1
;printf(s,"C","Python");}
#endif
#endif/*"""
print s%("Python","C")
#*/

Syntax-highlighted version:

Python:

#if/*
"""*/1
main(){char*//"""
s="This program wasn't written in %s, it was built for %s!"
#if/*
"""*/1
;printf(s,"C","Python");}
#endif
#endif/*"""
print s%("Python","C")
#*/

C (poor highlighting, sorry)

#if/*
"""*/1
main(){char*//"""
s="This program wasn't written in %s, it was built for %s!"
#if/*
"""*/1
;printf(s,"C","Python");}
#endif
#endif/*"""
print s%("Python","C")
#*/
\$\endgroup\$
2
\$\begingroup\$

C and ecpp, 140 bytes

#ifdef ECPP
#replace "C" "ECPP"
#replace "ECPP" "C"
#endif
main(){puts("This program wasn't written in ""C"", it was built for ""ECPP""!");}

Try ecpp online!
Try C online!

The #ifdef and #endif avoid syntax errors in C. #replace "C" "ECPP" replaces the string "C" with the string "ECPP", and #replace "ECPP" "C" replaces the string "ECPP" with "C".

This takes advantage of C's automatic string concatenation capabilities.

\$\endgroup\$
2
\$\begingroup\$

Python/Clojure, 166 Bytes

#_()(println"This program wasn't written in Clojure, it was built for Python!")(comment
print("This program wasn't written in Python, it was built for Clojure!")#_())

Clojure – Try it online!

Python 3 – Try It Online!

Has room for improvement, not even a clever answer but I wanted to try it anyway.

Relies on the fact that #_() is an (unintentional?) reader no-op in Clojure (#_ will skip the next form, () is an empty form) yet starts a comment in python as python uses # for commenting.

\$\endgroup\$
9
  • \$\begingroup\$ Hello and welcome to PPCG. Would it be possible to provide two links to two online interpreters for ease fo verification? \$\endgroup\$ Mar 5 '19 at 9:25
  • \$\begingroup\$ Welcome to PPCG. I added some links to Try It Online (TIO), which is what we commonly use for easy demonstration. \$\endgroup\$
    – Kirill L.
    Mar 5 '19 at 10:21
  • \$\begingroup\$ @KirillL. Thanks, I forgot to add them. \$\endgroup\$
    – nihilazo
    Mar 5 '19 at 14:06
  • \$\begingroup\$ @nihilazo "Ignore next form (#_) The form following #_ is completely skipped by the reader." - from the official docs \$\endgroup\$
    – ASCII-only
    Mar 7 '19 at 5:49
  • \$\begingroup\$ 156? \$\endgroup\$
    – ASCII-only
    Mar 7 '19 at 5:53
2
\$\begingroup\$

Haskell/Standard ML (MLton), 175 bytes

Explanation

Haskell's line comment marker, --, is a valid name for a Standard ML (SML) identifier. SML's function and value introduction keywords, fun and val, are valid Haskell identifiers. So we define -- in SML to be the identity function (which arbitrarily defines fun in Haskell to be id). We define i in SML to be the beginning of the output string, which makes val in Haskell a constant function evaluating to that string. Then we can hide our main Haskell program in an ML comment, and hide the ML comment delimiters from Haskell using --.

Haskell, 175 bytes

fun--id
 =id;
val i="This program wasn't written in ";--print(i^"Standard ML, it was built for Haskell!");(*
main=putStrLn$val 1++"Haskell, it was built for Standard ML!"-- *)

Try it online!

Standard ML (MLton), 175 bytes

fun--id
 =id;
val i="This program wasn't written in ";--print(i^"Standard ML, it was built for Haskell!");(*
main=putStrLn$val 1++"Haskell, it was built for Standard ML!"-- *)

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ "Then we can hide our main Haskell program in an ML comment that we hide from Haskell using --."? \$\endgroup\$
    – ASCII-only
    Mar 11 '19 at 3:34
  • \$\begingroup\$ @ASCII-only, is that better? \$\endgroup\$
    – dfeuer
    Mar 12 '19 at 2:14
  • 3
    \$\begingroup\$ It's easier to use @ to hide (* from Haskell. 159 bytes \$\endgroup\$ Mar 12 '19 at 3:53
  • \$\begingroup\$ @ØrjanJohansen, oh, that's very clever. I would never have thought to use an as-pattern like that, since it's otherwise so useless! \$\endgroup\$
    – dfeuer
    Mar 12 '19 at 4:00

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.