Least common multiple

From Rosetta Code
Revision as of 08:19, 29 April 2011 by Oenone (talk | contribs) (add Ada)
Task
Least common multiple
You are encouraged to solve this task according to the task description, using any language you may know.

Compute the least common multiple of two integers.

Given m and n, the least common multiple is the smallest positive integer that has both m and n as factors. For example, the least common multiple of 12 and 18 is 36, because 12 is a factor (12 × 3 = 36), and 18 is a factor (18 × 2 = 36), and there is no positive integer less than 36 that has both factors. As a special case, if either m or n is zero, then the least common multiple is zero.

One way to calculate the least common multiple is to iterate all the multiples of m, until you find one that is also a multiple of n.

If you already have gcd for greatest common divisor, then this formula calculates lcm.

One can also find lcm by merging the prime decompositions of both m and n.

References: MathWorld, Wikipedia.

Ada

lcm_test.adb: <lang Ada>with Ada.Text_IO; use Ada.Text_IO;

procedure Lcm_Test is

  function Gcd (A, B : Integer) return Integer is
     M : Integer := A;
     N : Integer := B;
     T : Integer;
  begin
     while N /= 0 loop
        T := M;
        M := N;
        N := T mod N;
     end loop;
     return M;
  end Gcd;
  function Lcm (A, B : Integer) return Integer is
  begin
     if A = 0 or B = 0 then
        return 0;
     end if;
     return abs (A * B) / Gcd (A, B);
  end Lcm;

begin

  Put_Line ("LCM of 12, 18 is" & Integer'Image (Lcm (12, 18)));
  Put_Line ("LCM of -6, 14 is" & Integer'Image (Lcm (-6, 14)));
  Put_Line ("LCM of 35, 0 is" & Integer'Image (Lcm (35, 0)));

end Lcm_Test;</lang>

Output:

LCM of 12, 18 is 36
LCM of -6, 14 is 42
LCM of 35, 0 is 0

AutoHotkey

<lang autohotkey>LCM(Number1,Number2) {

If (Number1 = 0 || Number2 = 0)
 Return
Var := Number1 * Number2
While, Number2
 Num := Number2, Number2 := Mod(Number1,Number2), Number1 := Num
Return, Var // Number1

}

Num1 = 12 Num2 = 18 MsgBox % LCM(Num1,Num2)</lang>

AWK

<lang awk># greatest common divisor function gcd(m, n, t) { # Euclid's method while (n != 0) { t = m m = n n = t % n } return m }

  1. least common multiple

function lcm(m, n, r) { if (m == 0 || n == 0) return 0 r = m * n / gcd(m, n) return r < 0 ? -r : r }

  1. Read two integers from each line of input.
  2. Print their least common multiple.

{ print lcm($1, $2) }</lang>

Example input and output:

$ awk -f lcd.awk
12 18
36
-6 14
42
35 0
0

bc

Translation of: AWK

<lang bc>/* greatest common divisor */ define g(m, n) { auto t

/* Euclid's method */ while (n != 0) { t = m m = n n = t % n } return (m) }

/* least common multiple */ define l(m, n) { auto r

if (m == 0 || n == 0) return (0) r = m * n / g(m, n) if (r < 0) return (-r) return (r) }</lang>

C#

<lang csharp>public static int Lcm(int m, int n)

   {
     int r = 0;
     Func<int, int, int> gcd = delegate(int m2, int n2)
                                 {
                                   while (n2!=0)
                                   {
                                     var t2 = m2;
                                     m2 = n2;
                                     n2 = t2%n2;
                                   }
                                   return m2;
                                 };
     
     try
     {
       if (m == 0 || n == 0)
         throw new ArgumentException();
       r = Math.Abs(m*n)/gcd(m, n);
     }
     catch(Exception exception)
     {
       Console.WriteLine(exception.Message);
     }
     return (r<0) ? -r : r;
   }</lang>

Clojure

<lang Clojure>(defn gcd [a b] (if (zero? b) a (recur b, (mod a b))))

(defn lcm [a b] (/ (* a b) (gcd a b)))</lang>


Common Lisp

Common Lisp provides the lcm function. It can accept two or more (or less) parameters.

<lang lisp>CL-USER> (lcm 12 18) 36 CL-USER> (lcm 12 18 22) 396</lang>

Here is one way to reimplement it.

<lang lisp>CL-USER> (defun my-lcm (&rest args) (reduce (lambda (m n) (cond ((or (= m 0) (= n 0)) 0) (t (abs (/ (* m n) (gcd m n)))))) args :initial-value 1)) MY-LCM CL-USER> (my-lcm 12 18) 36 CL-USER> (my-lcm 12 18 22) 396</lang>

In this code, the lambda finds the least common multiple of two integers, and the reduce transforms it to accept any number of parameters. The reduce operation exploits how lcm is associative, (lcm a b c) == (lcm (lcm a b) c); and how 1 is an identity, (lcm 1 a) == a.

D

<lang d>import std.stdio, std.math;

pure nothrow int lcm(in int m, in int n) in {

   assert(m != 0 && n != 0);

} body {

   int m2 = m;
   int n2 = n;
   while (n2 != 0) {
       auto t2 = m2;
       m2 = n2;
       n2 = t2 % n2;
   }
   return abs(abs(m * n) / m2);

}

void main() {

   writeln(lcm(12, 18));

}</lang> Output:

36

J

J provides the dyadic verb *. which returns the least common multiple of its left and right arguments.

<lang j> 12 *. 18 36

  12 *. 18 22

36 132

  *./ 12 18 22

396

  0 1 0 1 *. 0 0 1 1  NB. for boolean arguments (0 and 1) it is equivalent to "and"

0 0 0 1

  *./~ 0 1

0 0 0 1</lang>

Java

<lang java>

  import java.util.Scanner;
  public class LeastCommonMultiple
  {
     public static void main(String[] args)
     {
        Scanner aScanner = new Scanner(System.in);//allows user input
        int m, n, leastCommonMultiple;
     
        //prompts user for values to find the LCM for, then saves them to m and n
        System.out.print("Enter the value of m:");
        m = aScanner.nextInt();
        System.out.print("Enter the value of n:");
        n = aScanner.nextInt();
        
        int multipleOfM = m, multipleOfN = n;  
     	 
        /* this section increases the value of multipleOfM until it is greater  
        / than or equal to the multipleOfN, then does it again when the lesser 
        / becomes the greater--if they aren't equal*/
        if (m != n)
        {
           for ( ; multipleOfM != multipleOfN ; )
           {
              if (multipleOfM < multipleOfN)
              {  
                 for (	int i = 0; multipleOfM < multipleOfN; i++)
                 {
                    multipleOfM = m * i;
                 }
              }
              else
              {
                 for (int i = 0; multipleOfN < multipleOfM; i++)
                 {
                    multipleOfN = n * i;
                 }
              }
           }
           leastCommonMultiple = multipleOfN;//equals multpleOfM
        }
        else
        {
           leastCommonMultiple = m;
        }
        System.out.println("Least Common Multiple of " +
              m + " and " + n + " is: " + leastCommonMultiple); 
     }
  }

</lang>

PicoLisp

Using 'gcd' from Greatest common divisor#PicoLisp: <lang PicoLisp>(de lcm (M N)

  (or
     (=0 M)
     (=0 N)
     (abs (/ (* M N) (gcd M N))) ) )</lang>

Prolog

SWI-Prolog knows gcd. <lang Prolog>lcm(X, Y, Z) :- Z is abs(X * Y) / gcd(X,Y). </lang> Example :

 ?- lcm(18,12, Z).
Z = 36.

Python

gcd

Using the fractions libraries gcd function: <lang python>>>> import fractions >>> def lcm(a,b): return abs(a * b) / fractions.gcd(a,b) if a and b else 0

>>> lcm(12, 18) 36 >>> lcm(-6, 14) 42 >>> assert lcm(0, 2) == lcm(2, 0) == 0 >>> </lang>

Prime decomposition

This imports Prime decomposition#Python <lang python> import operator from prime_decomposition import decompose

def lcm(a, b):

   if a and b:
       da = list(decompose(abs(a)))
       db = list(decompose(abs(b)))
       merge= da
       for d in da:
           if d in db: db.remove(d)
       merge += db
       return reduce(operator.mul, merge, 1)
   return 0

if __name__ == '__main__':

   print( lcm(12, 18) )    # 36
   print( lcm(-6, 14) )    # 42
   assert lcm(0, 2) == lcm(2, 0) == 0</lang>

Iteration over multiples

<lang python>>>> def lcm(*values): values = set([abs(int(v)) for v in values]) if values and 0 not in values: n = n0 = max(values) values.remove(n) while any( n % m for m in values ): n += n0 return n return 0

>>> lcm(-6, 14) 42 >>> lcm(2, 0) 0 >>> lcm(12, 18) 36 >>> lcm(12, 18, 22) 396 >>> </lang>

Repeated modulo

Translation of: Tcl

<lang python>>>> def lcm(p,q): p, q = abs(p), abs(q) m = p * q if not m: return 0 while True: p %= q if not p: return m // q q %= p if not q: return m // p


>>> lcm(-6, 14) 42 >>> lcm(12, 18) 36 >>> lcm(2, 0) 0 >>> </lang>

Retro

This is from the math extensions library included with Retro.

<lang Retro>: gcd ( ab-n ) [ tuck mod dup ] while drop ;

lcm ( ab-n ) 2over gcd [ * ] dip / ;</lang>

Ruby

Ruby has an Integer#lcm method, which finds the least common multiple of two integers.

Library: rational

<lang ruby>irb(main):001:0> require 'rational' => true irb(main):002:0> 12.lcm 18 => 36</lang>

I can also write my own lcm method. This one takes any number of arguments, and works by iterating the multiples of m until it finds a multiple of n.

<lang ruby>def lcm(*args)

 args.inject(1) do |m, n|
   next 0 if m == 0 or n == 0
   i = m
   loop do
     break i if i % n == 0
     i += m
   end
 end

end</lang>

<lang ruby>irb(main):004:0> lcm 12, 18 => 36 irb(main):005:0> lcm 12, 18, 22 => 396</lang>

Tcl

<lang tcl>proc lcm {p q} {

   set m [expr {$p * $q}]
   if {!$m} {return 0}
   while 1 {

set p [expr {$p % $q}] if {!$p} {return [expr {$m / $q}]} set q [expr {$q % $p}] if {!$q} {return [expr {$m / $p}]}

   }

}</lang> Demonstration <lang tcl>puts [lcm 12 18]</lang> Output:

36

TI-83 BASIC

<lang ti83basic>lcm(12, 18)

              36</lang>