GCD / LCM Polyglots!

Your challenge is to make a program or function that outputs the GCD of its inputs in one language and the LCM of its inputs in another. Builtins for GCD or LCM (I'm looking at you, Mathematica) are allowed but not encouraged. There will be 2 inputs, which will always be positive integers, never greater than 1000.

Test Cases

Each line is one test case in the format x y => GCD(x,y) LCM(x,y):

1 1 => 1 1
1 2 => 1 2
4 1 => 1 4
3 4 => 1 12
7 5 => 1 35
18 15 => 3 90
23 23 => 23 23
999 1000 => 1 999000
1000 999 => 1 999000
1000 1000 => 1000 1000


See this pastebin for all possible inputs with 0 < x, y < 31. Note that different versions of the same languages count as different languages.

• So... an if based on a version of the language, if stored in a variable, is allowed?
– IS4
Apr 19, 2017 at 14:32
• @illidanS4 that is fine.
– user58826
Apr 19, 2017 at 17:04

C / C++, 7978 73 bytes

Thanks to @ETHproductions for saving a byte!

int f(int a,int b){int c,d=a*b;for(;a;b=c)c=a,a=b%a;auto e=.5;c=e?d/b:b;}


C calculates the GCD: Try it online!

C++ calculates the LCM: Try it online!

In C, auto e=.5 declares an integer variable with the auto storage class (which is the default), which is then initialized to 0, whereas in C++11 it declares a double, which is initialized to 0.5. So the variable's value will be truthy in C++ and falsy in C.

The function calculates the GCD with Euclid's algorithm, and the LCM by dividing the product of a and b by the GCD.

Omitting the return statement works at least on GCC. The 78 byte solution below should work with any compiler:

int f(int a,int b){int c,d=a*b;for(;a;b=c)c=a,a=b%a;auto e=.5;return e?d/b:b;}

• an explanation would be cool, if you can
– cat
Apr 18, 2017 at 13:36
• @cat Explanation added. Apr 18, 2017 at 14:26
• If I'm not mistaken, you can save a byte with for(;a;b=c)c=a,a=b%a; Apr 18, 2017 at 15:02
• @ETHproductions Thanks! I knew there was a reason to use for instead of while ;) Apr 18, 2017 at 15:13

Jelly / Actually, 2 bytes

00000000: 1e 67                                            .g


This is a hexdump (xxd) of the submitted program. It cannot be tested online because TIO doesn't support the CP437 encoding. @Mego was kind enough to verify that this works on Cygwin, which implements CP437 as intended for Actually.

Jelly: GCD

Jelly uses the Jelly code page, so it sees the following characters.

œg


Try it online!

How it works

œ is an incomplete token and thus ignored. g is the GCD built-in.

Actually: LCM

Actually uses CP 437, so it sees the following characters.

▲g


Try it online!

How it works

▲ is the LCM input. Since g (GCD) requires two integer inputs, it isn't executed.

Actually / Jelly, 3 bytes

00000000: 11 1c 67                                         ..g


This is a hexdump (xxd) of the submitted program.

Actually: GCD

Actually uses CP 437, so it sees the following characters.

◄∟g


Try it online!

How it works

     (implicit) Read a and b from STDIN and push them on the stack.
◄    Unassigned. Does nothing.
∟   Unassigned. Does nothing.
g  Pop a and b and push gcd(a,b).
(implicit) Write the result to STDOUT.


Jelly: LCM

Jelly uses the Jelly code page, so it sees the following characters.

×÷g


Try it online!

How it works

×÷g  Main link. Left argument: a. Right argument: b

×      Multiply; yield ab.
g    GCD; yield gcd(a,b).
÷     Division; yield ab/gcd(a,b) = lcm(a,b).


Note: The formula gcd(a,b)lcm(a,b) = ab holds because a and b are positive.

1 TIO actually uses UTF-8 for Actually. Since both the ASCII characters and the CP437 characters 0x11 and 0x1c are unassigned, the program works nevertheless.

Alice and Jelly, 9 bytes

Alice computes the LCM:

//L
oi@g


Try it online!

What looks like a space is really 0x7F, the DEL control character.

Jelly computes the GCD. Since Jelly uses its own code page which is only compatible with printable ASCII, the linefeed and DEL character turn into ½ and linefeed, respectively:

//L½oi@
g


Try it online!

Explanations

Jelly is trivial: the first line defines a nonsensical helper link, the second line is the actual program and it simply contains the GCD built-in.

Alice is a little bit trickier, but it also uses a built-in:

/   Reflect to SE. Switch to Ordinal.
While in Ordinal mode, the IP bounces diagonally up and down through the grid.
i   Read all input as a single string.
L   Compute the shortest common superstring of an empty string and the input. That
is simply the input itself, so this does nothing.
After two more bounces, the IP hits the top right corner and turns
around, continuing to bounce up and down while moving west.
L   Still does nothing.
i   Try to read more input, but this simply pushes an empty string.
/   Reflect to W. Switch to Cardinal.
The IP wraps to the last column.
L   Implicitly discard the empty string and convert the input to two integers.
Compute their LCM.
/   Reflect to NW. Switch to Ordinal.
The IP immediately reflects off the top boundary to move SW instead.
o   Implicitly convert the LCM to a string and print it.
Reflect off the bottom left corner and move back NE.
/   Reflect to S. Switch to Cardinal.
i   Try to read a byte, but we're at EOF, so this pushes -1 instead. Irrelevant.
The IP wraps back to the first line.
/   Reflect to NE. Switch to Ordinal.
The IP immediately reflects off the top boundary to move SE instead.
@   Terminate the program.

• What looks like a space doesn't really look like a space. Apr 19, 2017 at 17:14
• @EriktheOutgolfer depends on the font, I guess. Apr 19, 2017 at 17:28
• For me 0x7F (duh mini-markdown) has never looked like a space in any font, at least in my experience. But it always inserts that extra line spacing below the line it resides in... Apr 20, 2017 at 7:57

Octave / MATLAB, 66 61 bytes

@(x,y)gcd(x,y)^(1-2*any(version==82))*(x*y)^any(version==82))


Saved 5 bytes thanks to Foon. (x*y)^any() was of course shorter than 1+(x*y-1)*any().

Well, at least it doesn't use the builtin for lcm.

Explanation:

This uses the builtin gcd to calculate the Greatest common divisor.

In Octave, this is raised to the power of 1-2*any(version==82). any(version==82) is 0 in Octave, so this is simply gcd(x,y)^1. It's multiplied by (x*y)^any(version==82), or (x*y)^0 = 1.

For MATLAB, gcd is raised to the power of 1-2*any(version==82). any(version==82) is 1 in MATLAB, so this is gcd(x,y)^-1. It multiplied by (x*y)^any(version==82), or (x*y)^1 = x*y. This gives the Least common multiple, since lcm(x,y) == x*y/gcd(x,y) for positive numbers.

Jelly and MATL, 6 5 bytes

ZmD
g


This is a full program in either of the two languages. It computes the GCD in Jelly (Try it online!) and the LCM in MATL (Try it online!). The MATL program exits with an error (allowed by default) after producing the correct output.

Only ASCII characters are used, so they correspond to the same encoded bytes in the two languages.

Explanation of GCD in Jelly

ZmD    Unused link
g      Main link (gets called automatically). Builtin GCD function (g)


Explanation of LCM in MATL

ZmD    Compute LCM (builtin function Zm) and display immediately (D)
g      Tries to implicitly take input to do something with it (depending
on the type of the input). Since there is no input, it errors out


Julia 0.4 / Julia 0.5, 18 bytes

log.(1)==0?lcm:gcd


Evaluates to gcd in Julia 0.4 (Try it online!) and to lcm in Julia 0.5 (Try it online!).

How it works

In Julia 0.4, log.(1) is a shorthand for getfield(log,1), which returns the memory location of the log builtin, e.g., the pointer Ptr{Void} @0x00007f2846cb6660. The result is thus non-zero, the comparison is false, and the expression evaluates to gcd.

In Julia 0.5, a new function vectorization syntax was introduced. log.(1) is now a shorthand for broadcast(log,1), which – since 1 is not iterable – simply evaluates log(1). The result is thus zero, the comparison is true, and the expression evaluates to lcm.

Octave / MATLAB, 4442 41 bytes

eval(['@' 'lcm'-[5 0 9]*all(version-82)])


This defines an anonymous function for GCD (@gcd) in Octave, and for LCM (@lcm) in MATLAB.

Example in Octave (or Try it online!):

>> eval(['@' 'lcm'-[5 0 9]*all(version-82)])
warning: implicit conversion from numeric to char
ans = @gcd
>> ans(12,16)
ans =  4


Example in MATLAB:

>> eval(['@' 'lcm'-[5 0 9]*all(version-82)])
ans =
@lcm
>> ans(12,16)
ans =
48


JS (ES6), CGL (CGL Golfing Language), 31 bytes (non-competing)

The LCM feature of CGL was added after this challenge.

 g=(a,b)=>b?g(b,a%b):a
//-LⓍ


What looks like a space is actually a non-breaking space, a comment for CGL. JS computes the GCD:

g=(a,b)=>b?g(b,a%b):a


And CGL computes the LCM:

//  does nothing
- decrements the current stack number, resulting in it pointing to input
L computes the LCM of the first and second stack items and pushes it to the stack
Ⓧ prints out the last stack item


Try it out:

Snippetify( g=(a,b)=>b?g(b,a%b):a
//-LⓍ
);
<script src="https://programmer5000.com/snippetify.min.js"></script>
<input type = "number">
<input type = "number">

Whispers v1/Whispers v2, 51 bytes

> Input
> Input
>> R1
>> 1⊓2
>> 1⊔2
>> Output 4


Try it online! (Whispers v1)

Try it online! (Whispers v2)

How it works

The pivotal line is interestingly the only line that isn't executed by either language:

>> R1


In Whispers (both versions), lines which don't match one of a certain set of regex are completely ignored. As a result, lines containing invalid commands are simply skipped over by the interpreter. R is a command that returns the magnitude and angle of a vector, which was added in version 2. In version 1 however, it's an invalid command, so that line is removed.

In both versions, the execution pattern is the same: output the value on line 4, which is either the GCD or LCM of the inputs, depending on the version. In version 1, we remove the 3rd line, so line 4 is

>> 1⊔2


which simply runs the LCM command on the inputs. In version 2 however, the program is unchanged, meaning that line 4 is

>> 1⊓2


which is the GCD builtin applied to the two inputs.

Finally, in both versions, the value on line 4 is outputted and the program ends