• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] GCD and LCM

JASS:
library Commons // by Almia
    // Determines the greatest common divisor. 
    function GCD takes integer a, integer b returns integer
        local integer n
        if b == 0 then
            return a
        endif
        loop
            set n = a
            set a = b
            set b = ModuloInteger(n, a)
            if b == 0 then
                return a
            endif
        endloop
        return 0
    endfunction
    // Gets the lowest common multiple
    function LCM takes integer a, integer b returns integer
        local integer n = GCD(a, b)
        if n == 0 then
            return 0
        endif
        return a*b/n
    endfunction
	// Checks if two integers are relatively prime to each other
	function IsCoprime takes integer a, integer b returns integer
		return GCD(a, b) == 1
	endfunction
	/*
		Gets the totatives between 0 and n, that is the positive integers 
		less than or equal to n that are relatively prime to n.
	*/
	function Totient takes integer n returns integer
		local integer count = 0
		local integer i = 1
		if n < 0 then
			return 0
		endif
		loop
			if IsCoprime(n, i) then
				set count = count + 1
			endif
			set i = i + 1
			exitwhen i == n
		endloop
		return count + 1
	endfunction
endlibrary
 
Last edited:
Thanks :D

No, I wasn't missing a return statement

Yes you are. This compiles:


JASS:
library Commons
    // gets the greatest common divisor
    function GCD takes integer a, integer b returns integer
        local integer n
        if b == 0 then
            return a
        else
            loop
                set n = a
                set a = b
                set b = ModuloInteger(n, a)
                if b == 0 then
                    return a
                endif
            endloop
        endif
        return 0
    endfunction
    // Gets the lowest common multiple
    function LCM takes integer a, integer b returns integer
        return a*b/GCD(a,b)
    endfunction
endlibrary
The code seems to work correctly, however it would be best if you could calculate an array of integers instead of just two.
 
Is there a reason you don't re-usen?

JASS:
    function LCM takes integer a, integer b returns integer
        local integer n = GCD(a, b)
        if n == 0 then
            return 0
        endif
        return a*b/n
    endfunction
and this could also possibly be inlined if you don't check for zero.

JASS:
    function LCM takes integer a, integer b returns integer
        return a*b/GCD(a, b)
    endfunction
 
Uhh, if GCD was 0, then the thread would stop right?

Yeah, which is why I said possibly. It would get a speed boost if it was inlined. Same goes for if you re-usedinteger n

Im not sure, would this work for preventing thread crash?

JASS:
function LCM takes integer a, integer b returns integer
    return R2I(a*b/(GCD(a, b) + 0.0001))
endfunction
Not sure if it's a good idea though.
 
Level 6
Joined
Aug 26, 2009
Messages
192
gcd is never 0, except for both operands being 0. But in that case it's argueable if you can call it gcd, since 0 doesn't really divide 0.

Edit1: About totient function. This is going to be quite useless. Maybe you can use euler's product formular and save the primes in an array. This would at least allow calculating it till around 80k (the 8000th prime is that big), since it's not possible in warcraft to calculate the totient for bigger numbers with your method, this might be a much better implementation.

Edit2: Got a wurst implementation now which can calculate it at least up to 100k (result is 40k). Didn't test it higher. I have the first 8191 primes (84011), hence it should be possible calculating the totient function till around 168022. The op-limit might be an issue though.
 
Last edited:
Level 6
Joined
Aug 26, 2009
Messages
192
Are you actually serious? There were comments about how to code the totient function to make it actually viable. There was a comment about changing multiplication/division of your lcm. And you ignore it entirely, although both comments would make your functions better. I just said, that I made an implementation in Wurst to test the method I proposed. And it worked. So why the hell you ignore a complete post because there's a single word, which is too intelligent for you?
 
JASS:
function LCM takes integer a, integer b returns integer
    local integer n = GCD(a, b)
    if n == 0 then
        return 0
    endif
    return a*b/n
endfunction

This is stupid.

How can the greatest common divisor of two integers be 0?

Your GCD function may have a return 0 statement at the end, but that's only to keep the compiler's mouth shut. The statement is actually unreachable.

And NO, I refuse to allow anyone to have a library called "Commons".
What the hell is "Commons" anyway?

Try something like Diophantine or Arithmetic. NumberTheory works too, because it is the study that revolves around properties of integers, primes especially.
 
Top