Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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

Anyone game for some good old fashioned GCD golf?

your inputs are unsigned 32bit ints on an interface of your choice (stdin, EAX EBX, however you want to snag them).

Do not use builtin GCD functions in languages. While one byte answers are funny they somewhat defeat the point of the exercise when the algorithm is so simple.

Code length will be measured in bytes. The shortest code in bytes wins.

share|improve this question
4  
Now that the question's generalised (and looking good!) - are 0s are allowed in the input? – Sp3000 yesterday
2  
@MikeShlanta if 0 is valid input then what output do you expect if both inputs are 0? (Since technically their GCD is infinity.) – Martin Büttner yesterday
    
Whops, that would be silly, my bad I will revise that. Turns out I'm not good at things haha – Mike Shlanta yesterday
3  
@MikeShlanta I can offer you to rewrite the challenge a bit to adopt the style we use for most of our challenges. Some changes I would make: in addition to GCD functions, disallow LCM (because they're trivially related as the Mathematica answer shows), maybe also prime factorisation, but I think the latter is probably not significantly shorter than the Euclidean algorithm anyway; specify that two zeroes is invalid input; reduce the number range to the language's default integer type or [0,255] whichever is greater; add test cases. – Martin Büttner 16 hours ago
2  
Let me know if you're up for that, then I'll make the changes and you can amend anything you don't like about the edit (or just roll it back). For future challenges I recommend using the sandbox where details like these can be sorted out before you get 25 answers which might be invalidated by trying to fix the challenge. – Martin Büttner 16 hours ago

29 Answers 29

Retina, 16

^(.+)\1* \1+$
$1

This doesn't use Euclid's algorithm at all - instead it finds the GCD using regex matching groups.

Try it online. - This example calculates GCD(8,12).

Input as 2 space-separated integers. Note that the I/O is in unary. If that is not acceptable, then we can do this:

Retina, 30

\d+
$*
^(.+)\1* \1+$
$1
1+
$.&

Try it online.

As @MartinBüttner points out, this falls apart for large numbers (as is generally the case for anything unary). At very a minimum, an input of INT_MAX will require allocation of a 2GB string.

share|improve this answer
2  
I would like to vote for this more – MickyT yesterday
1  
I was considering to post this, but unfortunately there's no way Retina can handle unary inputs up to 2^32-1 (even given enough time and memory), simply because .NET strings can't be longer than about 1G characters. Also in the second version, the implementation of $* casts the matched character to a signed integer (which is a bit of a bug I guess), so that conversion doesn't work for inputs over 2^31 either. – Martin Büttner 20 hours ago
    
@MartinBüttner do you think I should mark this as non-competing? – Digital Trauma 11 hours ago
    
The OP liked my 32bit signed integer asm version, so maybe just specify that your version operates on signed integers (if it does work properly on negative inputs). I did update my answer with code-size counts for unsigned versions, too, once I noticed that detail in the question.) – Peter Cordes 5 hours ago

i386 (x86-32) machine code, 8 bytes (9B for unsigned)

amd64 (x86-64) machine code, 9 bytes (10B for unsigned, or 14B 13B for 64b integers signed or unsigned)

Inputs are 32bit non-zero signed integers in eax and ecx. Output in eax.

## 32bit code, signed integers:  eax, ecx
08048420 <gcd0>:
 8048420:       99                      cdq               ; shorter than xor edx,edx
 8048421:       f7 f9                   idiv   ecx
 8048423:       92                      xchg   edx,eax    ; there's a one-byte encoding for xchg eax,r32.  So this is shorter but slower than a mov
 8048424:       91                      xchg   ecx,eax    ; eax = divisor(from ecx), ecx = remainder(from edx), edx = quotient(from eax) which we discard
 8048425:       41                      inc    ecx        ; saves 1B vs. test/jnz in 32bit mode
 8048426:       e2 f8                   loop   8048420 <gcd0>
 ; result in eax: gcd(a,0) = a

Mike Shlanta's answer was the starting point for this. My loop does the same thing as his, but for signed integers because cdq is one byter shorter than xor edx,edx. And yes, it does work correctly with one or both inputs negative. Mike's version will run faster and take less space in the uop cache (xchg is 3 uops on Intel CPUs, and loop is really slow on most CPUs), but this version wins at machine-code size.

edit: oops, I didn't notice the question required unsigned 32bit. Going back to xor edx,edx instead of cdq would cost one byte. div is the same size as idiv, and everything else can stay the same (xchg for data movement and inc/loop still work.)

Interestingly, for 64bit operand-size (rax and rcx), signed and unsigned versions are the same size. The signed version needs a REX prefix for cqo, so it's 2B, but the unsigned version can still use 2B xor edx,edx.

In 64bit code, inc ecx is 2B: the single-byte inc r32 and dec r32 opcodes were repurposed as REX prefixes. inc/loop doesn't save any code-size in 64bit mode, so you might as well test/jnz. Operating on 64bit integers adds another one byte per instruction in REX prefixes, except for loop or jnz. It's possible for the remainder to have all zeros in the low 32b (e.g. gcd((2^32), (2^32 + 1))), so we need to test the whole rcx and can't save a byte with test ecx,ecx. However, the slower jrcxz insn is only 2B:

## 64bit code, unsigned 64 integers:  rax, rcx
0000000000400610 <gcd_u64>:
  400610:       31 d2                   xor    edx,edx                ; same length as cqo
  400612:       48 f7 f1                div    rcx
  400615:       48 92                   xchg   rdx,rax
  400617:       48 91                   xchg   rcx,rax
  400619:       e3 02                   jrcxz  40061d <gcd_u64_end>   ; saves 1B over test rcx,rcx (3B) / jnz (2B)
  40061b:       eb f3                   jmp    400610 <gcd_u64>
000000000040061d <gcd_u64_end>:
## 0xD = 13 bytes of code
## result in rax: gcd(a,0) = a

Full runnable test program including a main that runs printf("...", gcd(atoi(argv[1]), atoi(argv[2])) ); source and asm output on the Godbolt Compiler Explorer, for the 32 and 64b versions. Tested and working for 32bit (-m32), 64bit (-m64), and the x32 ABI (-mx32).

GNU C inline asm source for the 32bit version (compile with gcc -m32 -masm=intel)

int gcd(int a, int b) {
    asm (// ".intel_syntax noprefix\n"
        ".p2align 4\n"                  // align to make size-counting easier
         "gcd0:   cdq\n\t"              // sign extend eax into edx:eax.  One byte shorter than xor edx,edx
         "        idiv    ecx\n"
         "        xchg    eax, edx\n"   // there's a one-byte encoding for xchg eax,r32.  So this is shorter but slower than a mov
         "        xchg    eax, ecx\n"   // eax = divisor(ecx), ecx = remainder(edx), edx = garbage that we will clear later
         "        inc     ecx\n"        // saves 1B vs. test/jnz in 32bit mode, none in 64b mode
         "        loop    gcd0\n"
        "gcd0_end:\n"
         : /* outputs */  "+a" (a), "+c"(b)
         : /* inputs */   // given as read-write outputs
         : /* clobbers */ "edx"
        );
    return a;
}

Normally I'd write a whole function in asm, but GNU C inline asm seems to be the best way to include a snippet which can have in/outputs in whatever regs we choose. As you can see, GNU C inline asm syntax makes asm ugly and noisy. It's also a really difficult way to learn asm.

It would actually compile and work in .att_syntax noprefix mode, because all the insns used are either single/no operand or xchg. Not really a useful observation.

share|improve this answer
    
Oh man that is clever as fuck. serious kudos to you – Mike Shlanta yesterday
    
@MikeShlanta: Thanks. If you like optimizing asm, have a look at some of my answers over on stackoverflow. :) – Peter Cordes yesterday
    
@MikeShlanta: I found a use for jrcxz after all in the uint64_t version :). Also, didn't notice that you'd specified unsigned, so I included byte counts for that, too. – Peter Cordes 5 hours ago

32-bit little-endian x86 machine code, 14 bytes

Generated using nasm -f bin

d231 f3f7 d889 d389 db85 f475

    gcd0:   xor     edx,edx
            div     ebx
            mov     eax,ebx
            mov     ebx,edx
            test    ebx,ebx
            jnz     gcd0
share|improve this answer
2  
I got this down to 8 bytes by using cdq and signed idiv, and one-byte xchg eax, r32 instead of mov. For 32bit code: inc/loop instead of test/jnz (I couldn't see a way to use jecxz, and there's no jecxnz). I posted my final version as a new answer since I think the changes are big enough to justify it. – Peter Cordes yesterday

T-SQL, 153 169 bytes

Someone mentioned worst language for golfing?

CREATE FUNCTION G(@ INT,@B INT)RETURNS TABLE RETURN WITH R AS(SELECT 1D,0R UNION ALL SELECT D+1,@%(D+1)+@B%(D+1)FROM R WHERE D<@ and D<@b)SELECT MAX(D)D FROM R WHERE 0=R

Creates a table valued function that uses a recursive query to work out the common divisors. Then it returns the maximum. Now uses the euclidean algorithm to determine the GCD derived from my answer here.

Example usage

SELECT * 
FROM (VALUES
        (15,45),
        (45,15),
        (99,7),
        (4,38)
    ) TestSet(A, B)
    CROSS APPLY (SELECT * FROM G(A,B))GCD

A           B           D
----------- ----------- -----------
15          45          15
45          15          15
99          7           1
4           38          2

(4 row(s) affected)
share|improve this answer

Python 3, 31

Saved 3 bytes thanks to Sp3000.

g=lambda a,b:b and g(b,a%b)or a

Or for a 21 (saved 5 thanks to Sp3000) byte solution,

from math import*;gcd
share|improve this answer
2  
In Python 3.5+: from math import*;gcd – Sp3000 yesterday
    
@Sp3000 Nice, I didn't know they had moved it to math. – Morgan 'Venti' Thrappuccino yesterday
1  
While you're at it: g=lambda a,b:b and g(b,a%b)or a – Sp3000 yesterday
    
@Sp3000 Thanks! I just finished a recursive solution, but that's even better than what I had. – Morgan 'Venti' Thrappuccino yesterday

Jelly, 7 bytes

ṛß%ðḷṛ?

Recursive implementation of the Euclidean algorithm. Try it online!

If built-ins weren't forbidden, g (1 byte, built-in GCD) and ×÷æl (4 bytes, product divided by LCM) would achieve a better score.

How it works

ṛß%ðḷṛ?  Main link. Arguments: a, b

   ð     Convert the chain to the left into a link; start a new, dyadic chain.
 ß       Recursively call the main link...
ṛ %        with b and a % b as arguments.
     ṛ?  If the right argument (b) is non-zero, execute the link.
    ḷ    Else, yield the left argument (a).
share|improve this answer
    
That almost feels like cheating haha, I may have to specify that answers can't use butlins... – Mike Shlanta yesterday
7  
If you decide to do so, you should do it quickly. It would currently invalidate three of the answers. – Dennis yesterday
    
Notice he specified length is in bytes -- those characters are mostly > 1 byte in UTF8. – cortices yesterday
3  
@cortices Yes, all code golf contests are scored in bytes by default. However, Jelly doesn't use UTF-8, but a custom code page that encodes each of the 256 characters it understands as a single byte. – Dennis 23 hours ago
    
@Dennis ah, clever. – cortices 3 hours ago

Haskell, 19 bytes

a#0=a
a#b=b#rem a b

Usage example: 45 # 35-> 5.

Euclid, again.

PS: of course there's a built-in gcd, too.

share|improve this answer
    
you should explain the trick that reverses the input order to avoid the conditional check – proud haskeller 3 hours ago

MATL, 7 bytes

pG1$Zm/

Try it Online!

Explanation

Since we can't explicitly use the builtin GCD function (Zd in MATL), I have exploited the fact that the least common multiple of a and b times the greatest common denominator of a and b is equal to the product of a and b.

p       % Grab the input implicitly and multiply the two elements
G       % Grab the input again, explicitly this time
1$Zm    % Compute the least-common multiple
/       % Divide the two to get the greatest common denominator
share|improve this answer
    
You can save one byte with two separate inputs: *1MZm/ – Luis Mendo 9 hours ago

Julia, 3 bytes

gcd

Julia, 21 bytes

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

Recursive implementation of the Euclidean algorithm.

share|improve this answer

C#, 22

x=a,b=>b<1?a:x(b,a%b);
share|improve this answer

Javascript, 21 bytes.

I think I'm doing this right, I'm still super new to Javascript.

g=a=>b=>b?a:g(b)(a%b)
share|improve this answer
    
That won't work. You define g as curried monads, yet use is as a dyadic function. – Dennis yesterday
    
@Dennis I think I just fixed it? Like I said, super new to JS. – Morgan 'Venti' Thrappuccino yesterday
2  
Yes, that works. For the record, g=(a,b)=>b?a:g(b,a%b) is equally short. – Dennis yesterday
    
@Dennis Ahhhh, that's what I was missing. I forgot the parens around the arguments and it was throwing syntax errors. – Morgan 'Venti' Thrappuccino yesterday
    
Did you intend to put the ternary values the other way around? g=a=>b=>b?g(b)(a%b):a – user81655 yesterday

GML, 57 bytes

a=argument0
b=argument1
while b{t=b;b=a mod b;a=t}return a
share|improve this answer

Delphi 7, 148

Well, I think I've found the new worst language for golfing.

unit a;interface function g(a,b:integer):integer;implementation function g(a,b:integer):integer;begin if b=0then g:=a else g:=g(b,a mod b);end;end.
share|improve this answer
    
Oh I don't know, parenthetic is pretty poor for golfing – MickyT yesterday

TI-Basic, 10 bytes

Prompt A,B:gcd(A,B

17 byte solution without gcd( built-in

Prompt A,B:abs(AB)/lcm(A,B

27 byte solution without gcd( or lcm( built-in:

Prompt A,B:While B:B→T:BfPart(A/B→B:T→A:End:A

35 byte recursive solution without gcd( or lcm( built-ins (requires 2.53 MP operating system or higher, must be named prgmG):

If Ans(2:Then:{Ans(2),remainder(Ans(1),Ans(2:prgmG:Else:Disp Ans(1:End

You would pass arguments to the recursive variant as {A,B} so for example {1071, 462}:prgmG would yield 21.

share|improve this answer
    
Color me impressed. – Mike Shlanta yesterday
    
Thanks, @MikeShlanta – Timtech yesterday
    
You should probably mention that the last one needs to be saved as prgmG. – quartata yesterday
    
Thanks @quartata, I added it in. – Timtech yesterday

Python 3.5, 70 82 73 bytes:

lambda*a:max([i for i in range(1,max(*a)+1)if not sum(g%i for g in[*a])])

The not in this case will make sure the sum all the numbers in *args modulo i are zero.

Also, now this lambda function can take in as many values as you want it to, as long as the amount of values is >=2, unlike the gcd function of the math module. For instance, it can take in the values 2,4,6,8,10 and return the correct GCD of 2.

share|improve this answer
    
You're under arrest for multichar variable names. (Or function arguments, but whatever) – CatsAreFluffy yesterday

Ruby, 23 bytes

g=->a,b{b>0?a:g[b,a%b]}

remember that ruby blocks are called with g[...] or g.call(...), instead of g(...)

partial credits to voidpigeon

share|improve this answer
2  
Instead of g.call(a,b) you can use g[a,b]. Instead of proc{|a,b|, you can use ->a,b{. – voidpigeon yesterday
1  
You can also save one byte by using b>0 instead of b<=0 and switching the order of the other operands. – voidpigeon yesterday
    
Thanks i will upd – Luis Masuelli yesterday

Oracle SQL 11.2, 104 bytes

SELECT MAX(:1*:2-LEVEL)FROM DUAL WHERE MOD(:1,:1*:2-LEVEL)+MOD(:2,:1*:2-LEVEL)=0 CONNECT BY LEVEL<:1*:2;
share|improve this answer

Pyth, 2 bytes

iE

Try it here!

Input as integer on two separate lines. Just uses a builtin.

share|improve this answer
    
Haha, I like it. – Mike Shlanta yesterday
2  
If you change the input format, iF also works. In addition, I think M?HgH%GHG is the shortest no-builtin way of doing this. – FryAmTheEggman yesterday

05AB1E, 1 byte

Code:

¿

Explanation:

¿   # Implicit input, computes the greatest common divisor.
    # Input can be in the form a \n b, which computes gcd(a, b)
    # Input can also be a list in the form [a, b, c, ...], which computes the gcd of
      multiple numbers.

Try it online! or Try with multiple numbers.

share|improve this answer

Windows Batch, 76 bytes

Recursive function. Call it like GCD a b with file name gcd.

:g
if %2 equ 0 (set f=%1
goto d)
set/a r=%1 %% %2
call :g %2 %r%
:d
echo %f%
share|improve this answer

C, 28 bytes

A rather straightforward function implementing Euclid's algorithm. Perhaps one can get shorter using an alternate algorithm.

g(a,b){return b?g(b,a%b):a;}

If one writes a little main wrapper

int main(int argc, char **argv)
{
  printf("gcd(%d, %d) = %d\n", atoi(argv[1]), atoi(argv[2]), g(atoi(argv[1]), atoi(argv[2])));
}

then one can test a few values:

$ ./gcd 6 21
gcd(6, 21) = 3
$ ./gcd 21 6
gcd(21, 6) = 3
$ ./gcd 6 8
gcd(6, 8) = 2
$ ./gcd 1 1
gcd(1, 1) = 1
$ ./gcd 6 16
gcd(6, 16) = 2
$ ./gcd 27 244
gcd(27, 244) = 1
share|improve this answer

R, 52 61 bytes

As an unnamed function

function(a,b)max(which(a%%1:(C<-min(a,b))+b%%1:C<1))
share|improve this answer
    
Save a byte switching <- to = – bouncyball 2 hours ago

Hoon, 20 bytes

|=
{@ @}
d:(egcd +<)

--

Hoon #2, 39 bytes

|=
{a/@ b/@}
?~
b
a
$(a b, b (mod a b))

Oddly, the only implementation in Hoon's stdlib for GCD is the one in use for its RSA crypto, which also returns some other values. I have to wrap it in a function that takes only d from the output.

The other implementation is just the default recursive GCD definition.

share|improve this answer

Mathematica, 11 bytes

#2#/LCM@##&

Based off of the relation gcd(a, b)*lcm(a, b) = a*b. Not much else to see here.

share|improve this answer
    
Hey, I was going to post that! (No I wasn't, I didn't know that GCD existed.) – CatsAreFluffy yesterday
    
-1 LCMGCD. – CatsAreFluffy yesterday

><>, 32 bytes

::{::}@(?\=?v{:}-
.!09}}${{/;n/>

Accepts two values from the stack and apply the euclidian algorithm to produce their GCD.

You can try it here!

share|improve this answer

ARM machine code, 12 bytes:

assembly:

gcd: cmp r0, r1
     sublt r0, r0, r1
     bne gcd

Currently can't compile this, but each instruction in ARM takes 4 bytes. Probably it could be golfed down using THUMB-2 mode.

share|improve this answer
    
Nice job man anyone who does this in machine code gets serious props from me. – Mike Shlanta 8 hours ago

MATL, 10 bytes

No one seems to have used brute force up to now, so here it is.

t0):\a~f0)

Input is a column array with the two numbers (using ; as separator).

Try it online!

Explanation

t     % Take input [a;b] implicitly. Duplicate
0)    % Get second number, b
:     % Array [1,2,...,b]
\     % Modulo operation with broadcast. Gives a 2×b array
a~    % 1×b array that contains true if the two modulo operations gave 0
f0)   % Index of last true value. Implicitly display
share|improve this answer

Cubix, 12 bytes

?v%.II^<@O;<

This wraps onto the cube as follows

    ? v
    % .
I I ^ < @ O ; <
. . . . . . . .
    . .
    . .

Uses the Euclidean Method.

II Two numbers are grabbed from STDIN and put on the stack
^ Flow redirected up
% Mod the Top of Stack. Remainder left on top of stack
? If TOS 0 then carry on, otherwise turn right
v.< If not 0 then redirect back to the mod
< If 0 then redirect into the out sequence
; drop TOS, O output TOS and @ end

share|improve this answer

Javascript, 42 bytes

n=(x,y)=>{for(k=x;x%k+y%k>0;k--);alert(k)}
I could get it down to ~32 with Grond, but whatever

share|improve this answer

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.