Project Euler 5 in Python - How can I optimize my solution?

后端 未结 20 897
醉梦人生
醉梦人生 2020-11-30 08:00

I\'ve recently been working on Project Euler problems in Python. I am fairly new to Python, and still somewhat new as a programmer.

In any case, I\'ve ran into a sp

相关标签:
20条回答
  • 2020-11-30 08:42

    Here is program in C language. Cheers

    #include <stdio.h>
    #include <stdlib.h>
    //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?
    bez_ost(int q)
    {
        register br=0;
        for( register i=1;i<=20;i++)
        if(q%i==0)
        br++;
    
        if(br==20)
        return 1;
        return 0;
    }
    
    int main()
    {
       register j=20;
       register ind=0;
    
       while(ind!=1)
       {
           j++;
           if(bez_ost(j))
           break;
       }
       fprintf(stdout,"\nSmallest positive number that is evenlu divisible by all of the numbers from 1 to 20 is: %d\n\a",j);
       system("Pause");
    
    }
    
    0 讨论(0)
  • 2020-11-30 08:43

    Here i have also done using prime factorization way.

    #!/usr/bin/env python
    import math
    def is_prime(num):
        if num > 1:
            if num == 2:
                return True
            if num%2 == 0:
                return False
            for i in range(3, int(math.sqrt(num))+1, 2):
                if num%i == 0:
                    return False
            return True
        return False
    
    def lcm(number):
        prime = []
        lcm_value = 1
        for i in range(2,number+1):
            if is_prime(i):
                prime.append(i)
        final_value = []
        for i in prime:
            x = 1
            while i**x < number:
                x = x + 1
            final_value.append(i**(x-1))
        for j in final_value:
            lcm_value = j * lcm_value
        return lcm_value
    
    if __name__ == '__main__':
        print lcm(20)
    

    After checking how much time it has taken, it was not bad at all.

    root@l-g6z6152:~/learn/project_euler# time python lcm.py

    232792560
    
    real    0m0.019s
    user    0m0.008s
    sys 0m0.004s
    
    0 讨论(0)
  • 2020-11-30 08:43

    A typescript variant that seems to be relatively quick, leveraging recursion and known facts.

    describe(`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?`,
    () => {
      it("prooves the example: 10", () => smallestWithoutRemainder(10).should.be.equal(2520));
      it("prooves 1", () => smallestWithoutRemainder(1).should.be.equal(1));
      it("prooves 2", () => smallestWithoutRemainder(2).should.be.equal(2));
      it("prooves 3", () => smallestWithoutRemainder(3).should.be.equal(6));
      it("prooves 4", () => smallestWithoutRemainder(4).should.be.equal(12));
      it("prooves 5", () => smallestWithoutRemainder(5).should.be.equal(60));
      it("prooves 6", () => smallestWithoutRemainder(6).should.be.equal(60));
      it("prooves 7", () => smallestWithoutRemainder(7).should.be.equal(420));
      it("prooves 8", () => smallestWithoutRemainder(8).should.be.equal(840));
      it("prooves 9", () => smallestWithoutRemainder(9).should.be.equal(2520));
      it("prooves 12", () => smallestWithoutRemainder(12).should.be.equal(27720));
      it("prooves 20", () => smallestWithoutRemainder(20).should.be.equal(232792560));
      it("prooves 30", () => smallestWithoutRemainder(30).should.be.equal(2329089562800));
      it("prooves 40", () => smallestWithoutRemainder(40).should.be.equal(5342931457063200));
    });
    
    let smallestWithoutRemainder = (end: number, interval?: number) => {
      // What do we know?
      // - at 10, the answer is 2520
      // - can't be smaller than the lower multiple of 10
      // - must be an interval of the lower multiple of 10
      // so:
      // - the interval and the start should at least be divisable by 'end'
      // - we can recurse and build on the results before it.
      if (!interval) interval = end;
      let count = Math.floor(end / 10);
      if (count == 1) interval = 2520;
      else if (count > 1) interval = smallestWithoutRemainder((count - 1) * 10, interval);
    
      for (let i = interval; true; i += interval) {
        let failed = false;
        for (let j = end; j > 1; j--) {
          if (i % j != 0) {
            failed = true;
            break;
          }
        }
        if (!failed) return i;
      }
    }
    
    0 讨论(0)
  • 2020-11-30 08:46

    I've had the same problem. The algorithm seems to be quite slow, but it does work nonetheless.

    result = list()
    xyz = [x for x in range(11, 21)]
    number = [2520]
    count = 0
    while len(result) == 0:
        for n in number:
            print n
            for x in xyz:
                if n % x == 0:
                    count += 1
                elif n % x != 0:
                    count = 0
                    break
        if count == 10:
            result.append(number[0])
        elif count != 10:
            number[0] += 1
    
    print result 
    

    This was the algorithm I made.

    0 讨论(0)
  • 2020-11-30 08:47

    Here's an observation on this problem. Ultimately, it takes 48 iterations to find the solution.

    Any number that is divisible by all of the numbers from 1..20 must be divisible by the product of the primes in that range, namely 2, 3, 5, 7, 11, 13, 17, and 19. It cannot be smaller than the product of these primes, so let's use that number, 232,792,560, as the increment, rather than 20, or 2,520, or some other number.

    As it turns out, 48 * 232,792,560 is divisible by all numbers 1..20. By the way, the product of all of the non-primes between 1..20 is 66. I haven't quite figured out the relationship between 48 and 66 in this context.

    0 讨论(0)
  • 2020-11-30 08:49

    I got the solution in 0.066 milliseconds (only 74 spins through a loop) using the following procedure:

    Start with smallest multiple for 1, which = 1. Then find the smallest multiple for the next_number_up. Do this by adding the previous smallest multiple to itself (smallest_multiple = smallest_multiple + prev_prod) until next_number_up % smallest_multiple == 0. At this point smallest_multiple is the correct smallest multiple for next_number_up. Then increment next_number_up and repeat until you reach the desired smallest_multiple (in this case 20 times). I believe this finds the solution in roughly n*log(n) time (though, given the way numbers seem to work, it seems to complete much faster than that usually).

    For example:

    1 is the smallest multiple for 1

    Find smallest multiple for 2

    Check if previous smallest multiple works 1/2 = .5, so no

    previous smallest multiple + previous smallest multiple == 2.

    Check if 2 is divisible by 2 - yes, so 2 is the smallest multiple for 2

    Find smallest multiple for 3

    Check if previous smallest multiple works 2/3 = .667, so no

    previous smallest multiple + previous smallest multiple == 4

    Check if 4 is divisible by 3 - no

    4 + previous smallest multiple == 6

    Check if 6 is divisible by 3 - yes, so 6 is the smallest multiple for 3

    Find smallest multiple for 4

    Check if previous smallest multiple works 6/4 = 1.5, so no

    previous smallest multiple + previous smallest multiple == 12

    Check if 12 is divisble by 4 - yes, so 12 is the smallest multiple for 4

    repeat until 20..

    Below is code in ruby implementing this approach:

    def smallestMultiple(top)
        prod = 1
        counter = 0
        top.times do
            counter += 1
            prevprod = prod
            while prod % counter != 0
                prod = prod + prevprod
            end
        end
        return prod
    end
    
    0 讨论(0)
提交回复
热议问题