Project Euler: Problem 1 (Possible refactorings and run time optimizations)

前端 未结 13 2043
半阙折子戏
半阙折子戏 2020-12-11 08:35

I have been hearing a lot about Project Euler so I thought I solve one of the problems in C#. The problem as stated on the website is as follows:

If w

相关标签:
13条回答
  • 2020-12-11 09:02

    That's basically the same way I did that problem. I know there were other solutions (probably more efficient ones too) on the forums for project-euler.

    Once you input your answer going back to the question gives you the option to go to the forum for that problem. You may want to look there!

    0 讨论(0)
  • 2020-12-11 09:07

    You can come up with a closed form solution for this. The trick is to look for patterns. Try listing out the terms in the sum up to say ten, or twenty and then using algebra to group them. By making appropriate substitutions you can generalize that to numbers other than ten. Just be careful about edge cases.

    0 讨论(0)
  • 2020-12-11 09:08
    Your approach is brute force apprach, The time complexity of the following approach is O(1), Here we     
    are dividing the given (number-1) by 3, 5 and 15, and store in countNumOf3,countNumOf5, countNumOf15.
    Now we can say that 3 will make AP, within the range of given (number-1) with difference of 3. 
    suppose you are given number is 16, then 
    3=> 3, 6, 9, 12, 15= sum1=>45
    5=> 5, 10, 15  sum2=> 30
    15=> 15 =>   sum3=15  
    Add sum= sum1 and sum2
    
    
    Here 15 is multiple of 3 and 5  so remove sum3 form sum, this will be your answer. **sum=sum-    
    sum3** please check link of my solution on http://ideone.com/beXsam]
    
    import java.util.*;
    class Multiplesof3And5 {        
            public static void main(String [] args){
                Scanner scan=new Scanner(System.in);
                int num=scan.nextInt();
                System.out.println(getSum(num));
            }    
            public static  long getSum(int n){
                int countNumOf3=(n-1)/3;//             
                int countNumOf5=(n-1)/5;           
                int countNumOf15=(n-1)/15;            
                long sum=0;           
                sum=sumOfAP(3,countNumOf3,3)+sumOfAP(5,countNumOf5,5)-sumOfAP(15,countNumOf15,15);
                return sum;
            }
            public static int sumOfAP(int a, int n, int d){
                return (n*(2*a +(n -1)*d))/2;
            }
    }
    
    0 讨论(0)
  • 2020-12-11 09:13

    Refactoring @mbeckish's very clever solution:

    public int eulerProblem(int max) {
        int t1 = f(max, 3);
        int t2 = f(max, 5);
        int t3 = f(max, 3 * 5);
        return t1 + t2 - t3;
    }
    
    private int f(int max, int n) {
        int a = (max - 1) / n;
        return n * a * (a + 1) / 2;
    }
    
    0 讨论(0)
  • 2020-12-11 09:17

    Updated to not double count numbers that are multiples of both 3 and 5:

    int EulerProblem(int totalNum)
    {
       int a = (totalNum-1)/3;
       int b = (totalNum-1)/5;
       int c = (totalNum-1)/15;
       int d = a*(a+1)/2;
       int e = b*(b+1)/2;
       int f = c*(c+1)/2;
       return 3*d + 5*e - 15*f;
    }
    
    0 讨论(0)
  • 2020-12-11 09:18

    Try this, in C. It's constant time, and there's only one division (two if the compiler doesn't optimize the div/mod, which it should). I'm sure it's possible to make it a bit more obvious, but this should work.

    It basically divides the sum into two parts. The greater part (for N >= 15) is a simple quadratic function that divides N into exact blocks of 15. The lesser part is the last bit that doesn't fit into a block. The latter bit is messier, but there are only a few possibilities, so a LUT will solve it in no time.

    const unsigned long N = 1000 - 1;
    const unsigned long q = N / 15;
    const unsigned long r = N % 15;
    const unsigned long rc = N - r;
    
    unsigned long sum = ((q * 105 + 15) * q) >> 1;
    
    switch (r) {
        case 3  : sum += 3  + 1*rc ; break;
        case 4  : sum += 3  + 1*rc ; break;
        case 5  : sum += 8  + 2*rc ; break;
        case 6  : sum += 14 + 3*rc ; break;
        case 7  : sum += 14 + 3*rc ; break;
        case 8  : sum += 14 + 3*rc ; break;
        case 9  : sum += 23 + 4*rc ; break;
        case 10 : sum += 33 + 5*rc ; break;
        case 11 : sum += 33 + 5*rc ; break;
        case 12 : sum += 45 + 6*rc ; break;
        case 13 : sum += 45 + 6*rc ; break;
        case 14 : sum += 45 + 6*rc ; break;
    }
    
    0 讨论(0)
提交回复
热议问题