1

I have method which should give the LCM of multiple numbers. It works with Java's reduce() method so the numbers 1,2,3 gives the LCM of 6, which is correct:

int lcmAnswer = Arrays.stream(numbers).reduce(1, (a, b) -> {
            int total =  lcmm(a, b);
            return total;
    }
);
System.out.println(lcmAnswer); // LCM(1, 2, 3) = 6

However if I don't use Java's reduce() method then the numbers 1,2,3 don't give me the LCM of 6. It gives me LCM(1, 2, 3) = 8, which is wrong:

int[] numbers = {1, 2, 3};
System.out.println(lcmm(1,2,3)); // LCM(1, 2, 3) = 8, which is wrong


private static int lcmm(int... numbers) {
    int  sum = 0;
    for (int i = 0; i<numbers.length -1; i++) {
        int curr = numbers[i];
        int next = numbers [i+1];
        sum += lcm(curr, next);
    }

    return sum;
}

private static int lcm(int p, int q) {
    // Return lowest common multiple.
    return p * q / gcd(p, q);
}

private static int gcd(int p, int q) {
    //Return greatest common divisor using Euclid's Algorithm.
    int temp;
    while (q != 0) {
        temp = q;
        q = p % q;
        p = temp;
    }
    return p;
}

Does someone has any idea what I'm doing wrong?

superkytoz
  • 1,267
  • 4
  • 23
  • 43
  • 4
    Sure - instead of doing `sum += lcm(curr, next)`, you should start with `sum = 1` and do `sum = lcm(sum, numbers[i])` for each `i`. Obviously, `sum` is probably not the best name for such a variable, either - may I suggest `lcm`? – Avi Aug 17 '20 at 20:56
  • 1
    As Avi already stated your calculation is wrong. Your code is calculating `lcm()` for 2 consecutive numbers in your array and sums those (i.e. the result will be equal to `lcm(1,2) + lcm(2,3)`) while `reduce()` will calculate it for the next number in the sequence and the result of the previous run or the initial value ( i.e. the end result will be equal to `lcm( lcm( lcm( 1, 1 ), 2 ), 3 )`). – Thomas Aug 17 '20 at 22:45
  • @Avi Why start with `sum = 1`? Is it because every number has 1 as a factor? – superkytoz Aug 18 '20 at 11:56
  • @superkytoz It's because the LCM of 1 and any other number will be the other number, which is the expected value for LCM of one number. – Avi Aug 18 '20 at 16:20

1 Answers1

1

Suppose we have four numbers a,b,c,d. To calculate LCM of a,b,c,d, we need to follow these steps:

Let the final LCM is RES.

  • Calculate LCM of first two numbers a and b. Assign the value to RES. So, RES = LCM(a,b).
  • Calculate LCM of RES and c. Update the value of RES. So, RES = LCM(RES,c).
  • Calculate LCM of RES and d. Update the value of RES. So, RES = LCM(RES,d).

The final value of RES will contain the LCM of a,b,c,d.

We can follow this algorithm to calculate LCM of multiple numbers.

Here is the implementation:

import java.util.*;
import java.lang.*;
import java.io.*;
 
class LCMMultiple{
    public static void main (String[] args) throws java.lang.Exception{
        int[] numbers = {1, 2, 3};
        System.out.println(getLcmMultiple(numbers));
 
    }
 
    private static int getLcmMultiple(int... numbers) {
        int lcm = 0;
        for (int i = 0; i<numbers.length -1; i++) {
            int curr = numbers[i];
            int next = numbers [i+1];
            if(lcm != 0){
                lcm = getLcm(lcm, getLcm(curr, next));
            }
            else{
                lcm = getLcm(curr, next);
            }
        }
        return lcm;
    }
 
    private static int getLcm(int p, int q) {
        // Return lowest common multiple.
        return p * q / getGcd(p, q);
    }
 
    private static int getGcd(int p, int q) {
        //Return greatest common divisor using Euclid's Algorithm.
        int temp;
        while (q != 0) {
            temp = q;
            q = p % q;
            p = temp;
        }
        return p;
    }    
}

Output:

6
arshovon
  • 13,270
  • 9
  • 51
  • 69