Sum of all the multiples of 3 or 5 below 1000 gives a wrong answer in C

前端 未结 7 1699
失恋的感觉
失恋的感觉 2020-12-22 05:27

Project Euler problem:

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9

相关标签:
7条回答
  • 2020-12-22 05:58

    Direct translation of your python code:

    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
      int sum = 0;
    
      for (int x = 0; x < 1000; x++)
      {
        if (x % 5 == 0 || x % 3 == 0)
          sum += x;
      }
    
      printf("%d", sum);
    }
    
    0 讨论(0)
  • 2020-12-22 06:09

    Your solution with for-loop will be O(n).

    I found a more generic solution O(1).

    Here we can use another multiplies, even non-primes.

    #include <stdio.h>
    
    long gcd(long a, long b) {  
        return b == 0 ? a : gcd(b, a % b);  
    }
    
    long lcm(long a, long b) {  
        return a / gcd(a, b) * b;  
    }  
    
    long sumMultiple(long mult, long to) {
        to = to / mult;
        to *= to + 1;
        return (to >> 1) * mult;
    }
    
    long calc(long a, long b, long n) {
        n--;
        return sumMultiple(a, n) + sumMultiple(b, n) - sumMultiple(lcm(a,b), n);
    }
    
    int main() {
        int n = 1000;
        printf("Sum of multiplies of 3 and 5 is %ld\n", calc(3,5,n));
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-22 06:10
    #include<stdio.h>
    int main()
    {
    int sum;
    int i;
    sum=0;
    for(i=0;i<1000;++i)
    {
    if((i%3==0)||(i%5==0))
       {
        sum=sum+i;
       }
    }
    
    printf("%d",sum);
    
    }
    

    Output is 233168

    0 讨论(0)
  • 2020-12-22 06:14

    Some numbers will be divisible by both 3 and 5, you should not add them twice. A code like this will give correct result:

    long int x,total = 0;
    
    for(x = 0; x < 1000; ++x)
    {
        if(x % 3 == 0)
            total = total + x;
        else if(x % 5 == 0)
            total = total + x;
    }
    
    printf("%ld", total);
    

    in the code above if else if make sure that if a number is divisible by 3 or by 5. And allow to sum up on this basis.

    It can further be optimized to:

    for(x= 0; x < 1000; ++x)
    {
        if(x%3 == 0 || x%5 == 0)
            total = total + x;
    }
    

    Above solution is O(n) for better time complexity O(1) we can use Arithmetic Progression with interval of 3 and 5.

    n = total number of multiples of given number(Num) in given range (1...R). in this case (1...1000)

    a1 = first multiple. Here it will be 3 or 5.

    an = last multiple. i.e 3Xn

    Hence, following code will calculate Sum of series with interval 3/5 (Num) for given range 1...lastOfRange (excluding lastOfRange).

    long SumOfSeries(long Num, long lastOfRange)
    {
        long multiplesCount = (lastOfRange-1) / Num; //(lastOfRange-1) to exlude the last number 1000 here
        long result = multiplesCount * (Num + (multiplesCount * Num)) / 2;//Num = a1, (multiplesCount * Num) = an.
        return result;
    }
    

    and this can be called as:

    long N = 1000;
    Sum = SumOfSeries(3, N) + SumOfSeries(5, N) - SumOfSeries(3*5, N);
    printf("%ld", total);
    
    0 讨论(0)
  • 2020-12-22 06:15

    For the fun of it, I decided on giving the problem some additional constraints.

    • The loop iterator can not take values that aren't a multiple
    • The numbers must be added to the sum in numerical order.

    int sum_multiples(long int m1,long int m2,long int lim)
    {
        long int sum=0;
        for(long int i=m1;i<lim;i=((i+m1)/m1)*m1>((i+m2)/m2)*m2?((i+m2)/m2)*m2:((i+m1)/m1)*m1) sum+=i;
        return sum;
    }
    int  main(int argc, char *argv[])
    {
        printf("Total: %ld \n",sum_multiples(3,5,1000));
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-22 06:19

    The answer can be computed with simple arithmetic without any iteration. Many Project Euler questions are intended to make you think about clever ways to find solutions without just using the raw power of computers to chug through calculations.

    Given positive integers N and F, the number of positive multiples of F that are less than N is floor((N-1)/F). (floor(x) is the greatest integer not greater than x.) For example, the number of multiples of 5 less than 1000 is floor(999/5) = floor(199.8) = 199.

    Let n be this number of multiples, floor((N-1)/F).

    The first multiple is F and the last multiple is nF. For example, with 1000 and 5, the first multiple is 5 and the last multiple is 199•5 = 995.

    The multiples are evenly spaced, so the average of all of them equals the average of the first and the last, so it is (F + nF)/2.

    The total of the multiples equals their average multiplied by the number of them, so the total of the multiples of F less than N is n • (F + nF)/2.

    As we have seen in other answers and in comments, adding the sum of multiples of 3 and the sum of multiples of 5 counts the multiples of both 3 and 5 twice. We can correct for this by subtracting the sum of those numbers. Multiples of both 3 and 5 are multiples of 15.

    Thus, we can compute the requested sum using simple arithmetic without any iteration:

    #include <stdio.h>
    
    
    static long SumOfMultiples(long N, long F)
    {
        long NumberOfMultiples = (N-1) / F;
        long FirstMultiple = F;
        long LastMultiple = NumberOfMultiples * F;
    
        return NumberOfMultiples * (FirstMultiple + LastMultiple) / 2;
    }
    
    
    int main(void)
    {
        long N = 1000;
        long Sum = SumOfMultiples(N, 3) + SumOfMultiples(N, 5) - SumOfMultiples(N, 3*5);
    
        printf("%ld\n", Sum);
    }
    

    As you do other Project Euler questions, you should look for similar ideas.

    0 讨论(0)
提交回复
热议问题