This algorithm wasn’t too bad. I knew that involved the Euclidean Algorithm for the Greatest Common Divisor(aka Greatest Common Factor), the Euclidean Algorithm for the Least Common Multiple (which depends on the computation of the GCD), and that my solution would depend on those two formulas. I also knew that I was not just dealing with two array elements. These elements denoted the min and max of a range of elements. In this case, a range of numbers.

My solution had to to achieve the following:

Find the least common multiple of a given array of 2 numbers and the range of numbers between them.

The two numbers provided will not necessarily be in numerical order, so the solution will have to account for that.

The arr containing the lcm of the range of numbers should not return in the form of an array, but as a number.

It was back to the provided arguments and expected outcomes drawing board to find common (or uncommon) pattern(s). I immediately noticed that all the arrays had ascending numbers except for one, which had descending numbers. I also saw that there were always only two numbers in each provided array.

The first thing to do however, was to start off the solution with the Euclid Algorithm for the Greatest Common Divisor followed by the Euclid Algorithm for the Least Common Multiple:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// Euclid Algorithm for the Greatest Common Divisor

functiongcd(a,b){

return!b

?a

:gcd(b,a%b);

}

// Euclid Algorithm for the Least Common Multiple

functionlcm(a,b){

returna*(b/gcd(a,b));

}

functionsmallestCommons(arr){

returnarr;

}

smallestCommons([5,1]);

By itself, with help from function gcd(), function lcm() only takes care of finding the least common multiple of the two numbers in the array argument. I had to figure out a way to come up with the lcm of ALL the numbers within the range of arr = [a, b]. I wanted to find a way of mimicking the .reduce() method without actually using it to achieve this. In other words, I wanted to find a way of accumulating the lcm of all the numbers between arr[0] and arr[1] and “reducing” them to one lcm. With the .reduce() method, I usually used three parameters: the previousValue/initialValue returned in the last invocation of the callback, the currentValue or the current element being processed in the array, and then the array reduce is called upon. However, I wanted to use a for loop, because I had a set range of numbers in each array to iterate, and it was the simplest and most direct approach. I also had to set up two variables and their associated values equivalent to the previousValue and currentValue parameters of the .reduce() method. Lastly, if the order of the numbers in the array argument switched from ascending order to descending order, I had to make sure to reverse it back to ascending order. So this is what I came up with next:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

// Euclid Algorithm for the Greatest Common Divisor

functiongcd(a,b){

return!b

?a

:gcd(b,a%b);

}

// Euclid Algorithm for the Least Common Multiple

functionlcm(a,b){

returna*(b/gcd(a,b));

}

// LCM of all numbers in the range of arr = [a, b];

functionsmallestCommons(arr){

vari,

result;

// large to small - small to large

if(arr[0]>arr[1]){

// only happens once. Means that the order of the arr reversed.

arr.reverse();

}

for(i=result=arr[0];i<=arr[1];i++){// all numbers up to arr[1] are arr[0].

result=lcm(i,result);// lcm() makes arr int an integer because of the arithmetic operator.

}

returnresult;

}

This actually comprises the complete solution. Let’s break it down:

First we have the function for the greatest common divisor. The solution for that function is necessary in order to get the least common multiple for two numbers, which comes right after.

I had to declare two variables within the local scope of smallestCommons(), so I declare var i, result at the same time. i represents the counter in the for loop, and result represents the result parameter in the lcm(i, result) recursive function, using counter i and the instance of the result variable in the for loop. But then we need to calculate the lcm within the range of and including the two numbers in the array argument provided to us. 1 and 5, in the solution here. Since the order of the numbers of one of the array arguments is opposite from the rest, I have to account for that and before anything else. That’s because I want to make sure the order of the elements in the array are reversed before any looping takes place. Makes sense? If not, examine what is going on in the for loop for the answer. Since the reverse order only happens once, I can use an if statement. This is represented by if (arr[0] > arr[1]) { arr.reverse(); }. This means that if the first element/number in the array is larger than the second, the order should be reversed.

The next part is the tricky part. This is where calculation of the lcm for the range 1 – 5 takes place. In order to understand what is going on, we have to examine the role that the for loop plays here and how it works. First of all, the way I set up this for loop differs from your typical for loop. Typically, a for loop looks something like this:

JavaScript

1

for(vari=0;i<num;i++){}

But I did:

JavaScript

1

for(i=result=arr[0];i<=arr[1];i++){}

For the first iteration of the loop, i = result which is = arr[0] which is equal to 1. i which is equal to 1 is <= arr[1], which is 5. and i++ means that after the iteration of the first loop, i will be incremented by 1 to equal 2. This will continue until i equals 5 and is then equal to arr[1], which is 5.

But that’s only the first part of the story. Following the for loop is the line result = lcm(i, result); This recursion of the lcm() function and its assignment to the result variable is what makes the magic happen.

When i and result are first equal to 1 in the for loop, i as parameter of lcm() is equal to 1 and result as parameter of lcm() is also equal to 1. result = lcm(1,1). lcm(1,1) = 1. Therefore, result = 1.

For the second iteration of the for loop, i = 2, and arr[0], therefore, is also = 2. the result variable to the left of the assignment operator = is equal to lcm(i, result). lcm(i, result) is lcm(2, 1) because the first result value from the first iteration of the for loop is carried into the lcm() function as a parameter for which the value is 1. Now result is = 2.

For the the third iteration of the for loop, i = 3, and arr[0] is = 3. result, the parameter of lcm(i, result) is equal to 2. result = lcm(3,2). lcm(3,2) is equal to 6. That means that result = 6.

For the fourth iteration of the for loop, i = 4, and arr[0] is = 4. result, the parameter of lcm(i, result) is equal to 6. result = lcm(4, 6). lcm(4, 6) is equal to 12. result is now = 12.

For the 5th and final iteration of the for loop, i = 5 and arr[0] = 5. result, the parameter of lcm(i, result) is equal to 12. result = lcm(5, 12). lcm(5, 12) = 60. The for loop stops, and result is returned at the end of the smallestCommons() function right before the closing curly bracket.

You may wonder why I haven’t been explaining how result to the left of the assignment operator works in relation to the result parameter within lcm(i, result)? Yes, it can definitely be confusing. I kept that for last. The result in the for loop refers to the result parameter in the lcm() function. The result to the left of the assignment operator following the for loop represents a RE-ASSIGNMENT of the result variable. Each time the for loop goes through an iteration, this result is re-assigned a new value of lcm(i, result). This new value then becomes the value, or rather result argument passed to the lcm() function after the next iteration of the loop.

I almost forgot to mention one last little detail my solution had to (and did) achieve, and I’ll explain why it did.

You may be wondering why arr is not returned as an array, but as a number. That’s because the lcm function involves arithmetic, and the use of arithmetic operators on number elements in an array result in the return of numbers and not arrays of numbers.

Related

Maria Campbell

Founder, Inter-Global Media Network, Inc., where I focus on Front End Development. as well as a digital photographer, videographer, blogger, broadcaster, and graphic designer. Genesis Framework user. I got my start 8+ years ago teaching myself HTML/CSS and Wordpress Development because I couldn't find anyone who could create what I wanted. I have been working with open source software ever since. I am an open source software evangelist, and a "Women in Technology" evangelist. A creative professional myself, I find Web Development to be both practical and creative. I love to cook, travel, read mysteries, love everything French, the beach at sunrise, my three cats, and hope to revisit the city of San Francisco one day.

Reader Interactions

Comment Policy: Your words are your own, so be nice and helpful if you can. Please, only use your real name and limit the amount of links submitted in your comment. We accept clean XHTML in comments, but don't overdo it please. Comments are moderated, so spammy or malicious links will be removed.