1

I'm currently trying to problem solve to the question 'What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?'

So far I've coded something up that seems to work, but takes a very long time. Furthermore, I'm having to huge amounts of 'and' statements within an if, which doesn't seem awfully efficient nor professional.

What can I do to optimise this code and make it tidier perhaps?

number = 1
result = 0

def divide(candidate):
    if candidate % 2 == 0 and candidate % 3 == 0 and candidate % 4 == 0 and candidate % 5 == 0 and candidate % 6 == 0 and candidate % 7 == 0 and candidate % 8 == 0 and candidate % 9 == 0 and candidate % 10 == 0 and candidate % 11 == 0 and candidate % 12 == 0 and candidate % 13 == 0 and candidate % 14 == 0 and candidate % 15 == 0 and candidate % 16 == 0 and candidate % 17 == 0 and candidate % 18 == 0 and candidate % 19 == 0 and candidate % 20 == 0:
        global result
        result = 1
        return 1

    else:
       global number
        result = 0
        number = number + 1
        return 0

while result == 0:
divide(number)

print "The lowest number divisible by all integers between 1-20 is:", number

Just to clarify, this isn't homework, I'm self-teaching myself Python and am attempting some ProjectEuler problems as part of this.

c3ntury
  • 73
  • 1
  • 3
  • 10
  • Is this homework? A hint: Do you really have to check for divisibility by ALL numbers between 1 and 20? If a number is divisible by 2 and 3, what other numbers between 1 and 20 is it also divisible by? – Praveen Gollakota Apr 10 '12 at 17:37
  • It's not homework, I'm just self-teaching python outside of my academics. And good point, thankyou! – c3ntury Apr 10 '12 at 17:38
  • 2
    You might be interested in googling for "least common multiple". – DSM Apr 10 '12 at 17:39
  • You have the wrong algorithm. See http://stackoverflow.com/questions/8416395/possible-optimization-in-my-code/8416789#8416789 for a solution in C. – Gunther Piez Apr 10 '12 at 18:00

4 Answers4

9

Your problem can be easiliy solved without the help of a computer, so an optimised version would simply print the answer. It's a bit hard to tell what amount of optimisation you would consider admissible.

Here's how to solve this question without a computer. The smallest number divisible by all numbers from 1 to 20 must be divisible by all prime powers occuring among these numbers. And, on the other hand, if we have a number divisible by all prime powers in this range, it will be divisble by all numbers from 1 to 20. Since prime powers with different bases are coprime, the product of all the highest prime powers for each prime in this range will be the answer. So here is the optimised code:

print 2**4 * 3**2 * 5 * 7 * 11 * 13 * 17 * 19
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • Wow, that truly is optimised! The one thing I don't quite understand is when you say 'the highest prime powers for each prime' :/ – c3ntury Apr 10 '12 at 17:53
  • 1
    @c3ntury: Read this as "for each prime in the range from 1 to 20, take the highest power of this prime occurring in this range." – Sven Marnach Apr 10 '12 at 17:57
  • Ah, so you've got 2**4 because that equals 16 and 3**2 because that'd be equal to 9? Why don't you just put 16 and 9? :s – c3ntury Apr 10 '12 at 18:00
  • @c3ntury: I even di at first, but then I thought it might be clearer this way. Obviously I was wrong. :) – Sven Marnach Apr 10 '12 at 18:20
  • 1
    *"the product of all the highest prime powers for each prime in this range will be the answer"* - It's helpful to mention *how* to find the exponent ("prime power"). If `p` is our prime (ex. 2) and `n` is our max (ex. 20), then the exponent is `floor(log_p(n))`. The primes themselves can be found by sieving. – BlueRaja - Danny Pflughoeft Apr 10 '12 at 18:26
2

You can start by eliminating numbers that are factors of previous numbers. All numbers divisible by 4 are divisible by 2. All numbers divisible by 10 are divisible by 5, All numbers divisible by 9 are divisible by 3, etc.

jsmith
  • 565
  • 3
  • 14
  • 28
  • Thanks, I'll quickly change my code to reflect that. Is there any way to do it without 15 or so 'and's within the if? – c3ntury Apr 10 '12 at 17:40
  • @c3ntury - Put all of the numbers in a list, then iterate through the list and test each one. – bta Apr 10 '12 at 17:44
0

A very simple but quite efficient here is to use only prime numbers and their powers. Why do you have to consider their multiply, right? Reduce your "and" conditions to only 4,9,16,5,7,11,13,17,19

AakashM
  • 62,551
  • 17
  • 151
  • 186
Thiem Nguyen
  • 6,345
  • 7
  • 30
  • 50
  • Careful: just because you're divisible by 2 doesn't mean you're divisible by 4 or 8 or 16. – DSM Apr 10 '12 at 17:38
0

If it was me I'd just try to 'mod' (%) the prime numbers. I wouldn't use every number from 1 to 20.

Matt
  • 45
  • 5