Reputation: 80
The project Euler problem 5 is stated as : "2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?" Here's the c++ code for the function I'm using.
long long unsigned int rangeLCM(int n)
{
long long unsigned int ans=1;
for(int i=1;i<=n;i++)
{
if(ans%i!=0)
{
if(i%(ans%i)==0)ans*=(i/(ans%i));
else ans*=i;
}
}
return ans;
}
The code works well for the example stated in the problem and the problem itself{rangeLCM(10)=2520
and rangeLCM(20)=232792560
}, but I think it's not perfect and is missing out on some edge cases.
Instead of actually calculating the LCM(ans,i)
, I have checked that the bigger of the two(always ans
) is divisible by i
. If not, then ans
is multiplied by a number equal to i/(ans%i)
or i
depending on whether i
is divisible by (ans%i)
or not.
This is based on the following facts:
LCM(8,12)=24=12*(8/(12%8));
LCM(9,30)=90=30*(9/(30%9)
LCM(7,13)=91=13*7
However, it fails for the following types of cases:LCM(8,14)=56 != 8*14
Yet, the code for rangeLCM gives the right output for all inputs I have tried yet. Why?
Upvotes: 0
Views: 304
Reputation: 11284
Your logic does not work
if(i%(ans%i)==0)ans*=(i/(ans%i));
else ans*=i;
For example, if ans = 10
and i = 14
, so, the lcm should be 70, but in your code, it is 140.
The reason is, between ans
and i
, there are common divisors, but your code cannot detect that.
For experiment, I have written a small piece of code to check using Java.
class Solution {
public static void main(String[] args) {
long ans = 1;
for (long i = 1; i <= 40; i++) {
if (ans % i != 0) {
long before = (ans*i/gcd(ans,i));
if (i % (ans % i) == 0){
ans *= (i / (ans % i));
}else{
ans *= i;
}
System.out.println(ans + " " + before + " " + i);
}
}
}
public static long gcd(long a, long b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
}
Output
2 2 2
6 6 3
12 12 4
60 60 5
420 420 7
840 840 8
2520 2520 9
27720 27720 11
360360 360360 13
720720 720720 16
12252240 12252240 17
232792560 232792560 19
5354228880 5354228880 23
26771144400 26771144400 25
722820898800 80313433200 27
20961806065200 20961806065200 29
649815988021200 649815988021200 31
1299631976042400 1299631976042400 32
48086383113568800 48086383113568800 37
When i = 27, there is different between the correct answer and ans
The formula for lcm(a,b) is
lcm(a,b) = a*b/gcd(a,b)
With gcd is Greatest common divisor between two number a and b
Upvotes: 4
Reputation:
I think you are missing a lot of cases you have to implement the Euclidean algorithm at
if(i%(ans%i)==0)ans*=(i/(ans%i));
Upvotes: 0