Programming

Euler 9

So the other night I was a bit bored and decided to do something to pass the time. I first came across Project Euler a while ago, but had never gone further than problem #1. Boredom is a great motivator and I went through problems #2 thru #9 last night and I decided to post my solutions in search of better ones. Feel free to comment with your suggestions.

Project Euler’s Problem #9 statement is —

A Pythagorean triplet is a set of three natural numbers, $latex a < b < c$, for which,

[latex]a2 + b2 = c2[/latex]

For example, $latex 32 + 42 = 9 + 16 = 25 = 52$.

There exists exactly one Pythagorean triplet for which [pmath]a + b + c = 1000[/pmath].

Find the product [pmath]abc[/pmath].

Butt ugly, super slow, brute-force solution:

from sys import exit

def is_triplet(a, b, c):
        if a < b and b < c:
                return a ** 2 + b ** 2 == c ** 2

for a in range(0, 1000):
        for b in range(a + 1, 1000):
                for c in range(b + 1, 1000):
                        if a + b + c == 1000 and is_triplet(a, b, c):
                                print a * b * c
                                exit(0)

I’ll have to rethink this, as it’s really inefficient. As it is, it runs in 18.034s!

Updated: take a look at another take at this problem and algorithm.

Updated 2010/08/04: Gustavo Niemeyer pointed an obvious optimization to the algorithm above (written in C)—the innermost loop is unnecessary. I rewrote it in Python to see the difference:

from sys import exit

def is_triplet(a, b, c):
        return (a ** 2 + b ** 2 == c ** 2)

for a in range(1, 1000):
        for b in range(a + 1, (1000 - a) / 2):
                c = 1000 - a - b
                if is_triplet(a, b, c):
                        print "%d * %d * %d = %d" % (a, b, c, a * b * c)

From 18s to 0.076s. As well, following Eduardo Habkost’s suggestion, I used psyco and execution time went down to 0.023s.

Euler 6

So the other night I was a bit bored and decided to do something to pass the time. I first came across Project Euler a while ago, but had never gone further than problem #1. Boredom is a great motivator and I went through problems #2 thru #9 last night and I decided to post my solutions in search of better ones. Feel free to comment with your suggestions.

Project Euler’s Problem #6 statement is —

The sum of the squares of the first ten natural numbers is,

[pmath]12 + 22 + … + 102 = 385[/pmath]

The square of the sum of the first ten natural numbers is,

pmath2 = 552 = 3025[/pmath]

Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is [pmath]3025 – 385 = 2640[/pmath].

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

Can’t be more straightforward than that, really.

sqr_sum = 0
num_sum = 0
for i in range(1,100 + 1):
        num_sum += i
        sqr_sum += i**2

num_sum = num_sum**2
print sqr_sum - num_sum

I’m pretty sure Niemeyer could rewrite this in one line, but whatever. This runs in 0.015s.

Euler 5

So the other night I was a bit bored and decided to do something to pass the time. I first came across Project Euler a while ago, but had never gone further than problem #1. Boredom is a great motivator and I went through problems #2 thru #9 last night and I decided to post my solutions in search of better ones. Feel free to comment with your suggestions.

Project Euler’s Problem #5 statement is —

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?

My first attempt was using brute force, but it didn’t go very well. It took a considerable amount of time, so I decided to think about the problem a bit. In the end, it boils down to the a relation between the lesser common multiplier and the greater common divisor.

def gcd(a, b):
        if b== 0: return a
        return gcd(b, a % b)

def lcm(a, b):
        return a * b / gcd(a, b)

if __name__ == "__main__":
        b = 2
        for i in range(3,20):
                b = lcm(b, i)
        print b

While the original code took several seconds before I killed it, this runs in 0.015s.

Euler 4

So the other night I was a bit bored and decided to do something to pass the time. I first came across Project Euler a while ago, but had never gone further than problem #1. Boredom is a great motivator and I went through problems #2 thru #9 last night and I decided to post my solutions in search of better ones. Feel free to comment with your suggestions.

Project Euler’s Problem #4 statement is —

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 99.

Find the largest palindrome made from the product of two 3-digit numbers.

And here’s the solution.

def int_to_list(number):
  return map(int, str(number))

def is_palindrome(number):
  local_list = int_to_list(number)
  return local_list == list(reversed(local_list))

pal = 0
if __name__ == "__main__":
  for i in range(100,1000):
        for j in range(100,1000):
                if is_palindrome(i * j):
                        print "%d * %d = %d"%(i, j, i*j)
                        if i * j > pal:
                                pal = i * j

  print pal

Euler 3

So the other night I was a bit bored and decided to do something to pass the time. I first came across Project Euler a while ago, but had never gone further than problem #1. Boredom is a great motivator and I went through problems #2 thru #9 last night and I decided to post my solutions in search of better ones. Feel free to comment with your suggestions.

Project Euler’s Problem #3 statement is —

The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?

My solution is really ugly and is basically dumb-, brute-force.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<span class='line'><span class="c">#!/usr/bin/python</span>
</span><span class='line'>
</span><span class='line'><span class="kn">import</span> <span class="nn">math</span>
</span><span class='line'>
</span><span class='line'><span class="n">top_number</span> <span class="o">=</span> <span class="mi">600851475143</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">is_divisor</span><span class="p">(</span><span class="n">divisor</span><span class="p">):</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">top_number</span> <span class="o">%</span> <span class="n">divisor</span> <span class="o">==</span> <span class="mi">0</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">is_prime</span><span class="p">(</span><span class="n">divided</span><span class="p">):</span>
</span><span class='line'>        <span class="n">divisor</span> <span class="o">=</span> <span class="mi">3</span>
</span><span class='line'>        <span class="n">sqrt_divided</span> <span class="o">=</span> <span class="n">math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">divided</span><span class="p">)</span>
</span><span class='line'>        <span class="k">if</span> <span class="n">divided</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
</span><span class='line'>                <span class="k">return</span> <span class="n">true</span>
</span><span class='line'>        <span class="k">while</span> <span class="n">divisor</span> <span class="o"><=</span> <span class="n">sqrt_divided</span><span class="p">:</span>
</span><span class='line'>                <span class="k">if</span> <span class="n">divided</span> <span class="o">==</span> <span class="n">divisor</span><span class="p">:</span>
</span><span class='line'>                        <span class="k">return</span> <span class="bp">True</span>
</span><span class='line'>                <span class="k">elif</span> <span class="n">divided</span> <span class="o">%</span> <span class="n">divisor</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
</span><span class='line'>                        <span class="k">return</span> <span class="bp">False</span>
</span><span class='line'>                <span class="k">else</span><span class="p">:</span>
</span><span class='line'>                        <span class="n">divisor</span> <span class="o">+=</span> <span class="mi">2</span>
</span><span class='line'>        <span class="k">return</span> <span class="bp">True</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
</span><span class='line'>        <span class="n">count</span> <span class="o">=</span> <span class="mi">3</span>
</span><span class='line'>        <span class="n">go_to</span> <span class="o">=</span> <span class="n">top_number</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">first_list</span> <span class="o">=</span><span class="p">[]</span>
</span><span class='line'>        <span class="k">while</span> <span class="n">count</span> <span class="o"><=</span> <span class="n">go_to</span><span class="p">:</span>
</span><span class='line'>                <span class="k">if</span> <span class="n">is_divisor</span><span class="p">(</span><span class="n">count</span><span class="p">):</span>
</span><span class='line'>                        <span class="n">first_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">count</span><span class="p">)</span>
</span><span class='line'>                        <span class="n">go_to</span> <span class="o">=</span> <span class="n">top_number</span> <span class="o">/</span> <span class="n">count</span>
</span><span class='line'>                        <span class="n">first_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">go_to</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>                <span class="n">count</span> <span class="o">+=</span> <span class="mi">2</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">second_list</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">is_prime</span><span class="p">,</span> <span class="n">first_list</span><span class="p">)</span>
</span><span class='line'>        <span class="k">print</span> <span class="s">"</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="nb">max</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">second_list</span><span class="p">,</span> <span class="n">first_list</span><span class="p">))[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
</span><span class='line'>        <span class="n">main</span><span class="p">()</span>
</span>