Thursday, July 31, 2014

1 - Sums of Multiples

Problem 1:

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9.  The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

Background:

Mathematicians like to tell the story of a young Carl Gauss, a mathematician who made some very important advances in number theory, statistics, and electrostatics.  In some ways he has become mythologized, as is often the case with great historical figures.  A legend is told, passed down, and altered on each retelling.  The story becomes part of the culture of what ever group "owns" the story, and its members take pride in it.  There are dozens of such stories; King Arthur and his knights of the Round Table, Saint Benedict escaping being poisoned through divine intervention, George Washington refusing to lie after chopping down a cherry tree.  But the story I am about to tell regards a very young Carl Friedrich Gauss simply answering a question in math class.

When Carl Gauss was a child, we would call a tween by today's lingo, he attended school like any other boy his age. He lived in the Brunswick region of what was then the Holy Roman Empire. He was born in 1777, so by the time this event was taking place he would be about 13, making the year about 1790. This is a time where Europe is starting to enter what I consider to be the modern age. The United States had just won their Revolutionary war, and the French were in the throws of their own Revolution.

Carl Friedrich Gauss.jpgCurrently there are many stereotypes about Germans, one of the most notable being that they are very strict.  This stereotype also existed back in the 19th century, and it can also be inferred that the Germans were strict at the tail end of the 18th as well.  So, the young Carl Gauss was in class, and, as the story goes, the school master was fed up with his students goofing around.  As a punishment he told his students to add up the numbers from 1 to 100.  The school master expected the students to take some time with this problem.  At the very least a few minutes, but he was surprised when Carl Gauss, nearly instantly came up to him, and gave the answer 5050.  The school master was shocked one of his students found the answer so quickly.  He didn't know if this was correct off the top of his head, so he took out a very large book of problems and answers.  He found that Gauss was exactly correct in his calculation.  He hadn't missed carrying a digit or anything.

So how exactly did Gauss add up 100 numbers so quickly.  Was he a savant, like Rainman?  Well, no, he realized a very special pattern between the numbers.  All of the other kids in the classroom were doing what the school master intended.  They took one added two to get three, then added three to that and got six, added four and got ten, and so on.  Gauss realized that you could add the sum again, only in reverse order, to make the problem much easier.

$$ S = 1 + 2 + 3 + ... + 100 \\
S = 100 + 99 + 98 + ... + 1 \\
S+S = (100 + 1) + (2 + 99) + ( 3 + 98) + ... +(1 + 100) $$

Each of the sums in parentheses is clearly equal to 101, and since there are 100 instances of that sum we get the clean equation:
$$2S = 100*(101)$$
From here, it's trivial to solve, the product \(5050\) becomes easy to obtain.

More generally, the sequence is called an Arithmetic Sequence, i.e. a sequence in which any two consecutive terms share a common difference.  The sum of an Arithmetic Sequence is:
$$\sum\limits_{i = 1}^{n}a_i = \dfrac{n*(a_n+a_1)}{2}$$

The line of thinking Gauss used to get this answer so quickly is exactly the same line of thinking we need to solve Project Euler problems.  If each problem is a castle, then at the front of it will be walls, moats and ramparts, which will take time to get through.  Alternatively we could storm the castle by taking the secret entrance.  Gauss found that secret entrance to the problem of adding up arithmetic sequences, and in this problem we will put the same principle to use.

The Math:

The sum of a multiples of \(a\) is \(a*(1+2+3+...) = a*\frac{(n)(n+1)}{2}\) where \(n\) is the number of digits in the series.
So the sums of the multiples of 3 and 5 are:
$$ S_3 = 3 + 6 + 9 + 12 + 15 + ...  + 999\\
S_5 = 5 + 10 + 15 + 20 + ...  + 995 $$

As you might have noticed we cannot simple add these two sums together and get our answer, both of these sums include 15, in fact, they include all multiples of 15 less than 1000.

Thanks to what is known as the Inclusion-Exclusion Principle, which states that the union of two sets is equal to the sum of the two sets minus the intersection, we can solve the problem.  What this means in plain speak is we have twice as many multiples of 15 than we need, so we can subtract it out.

The basic formula for the sum of an arithmetic series is \( S = a * \dfrac{n*(n+1)}{2}\) where \(n\) is the number of numbers to add up.  The largest multiples of 3, 5, and 15 below 100 are 999, 995, and 990 respectively, so \(n\) for each would be 333, 199, and 66.

$$Ans = 3*\frac{333*334}{2} + 5*\frac{199*200}{2} - 15*\frac{66*67}{2}$$

To avoid divulging the answer to the puzzle, I will ignore explicitly stating it.

The Code:

Python:

Easy stuff here.  Basically just copying the line from above.

print(3*333*334/2 + 5*199*200/2 - 15*66*67/2)

Another cool python program that I found, note: I did not write this code, involves list comprehension.  there is a neat trick in python where a for loop statement can be used as an iterable object.

print(sum( x for x in range(1000) if x%3 == 0 or x%5 == 0))

This code automatically generates a list of multiples of 3 or 5 below 1000, and prints the sum.  In one line.  That is pretty wild.

If you don't recognise what the % sign means, it is called the modulo operator.  The expression x%n would give the remainder if you divided x by n.  For example 19%4 equals 3, because 19/4 is 4 with a remainder of 3.  If the remainder is 0, that means x would be divisible by n.  n times some number will give you x, meaning, by definition, x is a multiple of n.  Since this is what we want to find out, whether a number is a multiple of 3 or 5, it is used in the code.

Note, this kind of code is what many would consider to by "un-Pythonic."  It skirts understandability in favor of creating the shortest program possible.

My own code is pretty similar in that regard,  it would have been better if I defined the sums before instead of using numbers which seemingly come out of nowhere.  Those numbers are what are known in the programming world as "magic numbers."

Future problems will be much more complicated and I will do well to avoid them.

C:

I did something similar in C to that last python code.  But instead of calling the sum function, which there isn't in the default C, I had a variable called sum, which I added to if a number was a multiple of 3 or a multiple of 5.  When the loop terminates I print out the value of sum.

#include <stdio.h>

main()
{
    int sum;
    sum = 0;
    int i;
    for(i = 0; i<1000; ++i){
        if (i%3 == 0 || i%5 == 0){
            sum += i;
        }
    }
    printf("%d\n", sum);
}

Well, there it is, my first blog post.  I hope you enjoyed reading it as much as I did writing it.  I'm not exactly sure if I'll have a schedule.  All I can say is the next post will be out when it comes out.

0 - Introduction

About this Blog:

Recently I found out that Project Euler had been hacked.  While I found it terribly ironic that makers of a site dedicated to practicing programming skills fell victim to black-hat attack, the news of the outage also rekindled my interest in Project Euler.  I have played around with Project Euler on and off over the past three years, starting when I was just learning Python. Now that I am older, and know a thing or two more about programming, I want to try again.

So, I started doing the problems again, and on each new algorithm I wrote I found my comments getting longer and longer.  I pretty quickly realized that I had a lot to write about, and there might be other people interested in what I have to say.

I have always said that math is my first love, and math is largely what Project Euler is about.  Many of the problems can be solved using easy, brute force code style, but they might take minutes, if not longer to complete.  More often there is a little math trick which will create a short cut and let you solve the problem in an efficient manner.

Each blog post will contain the problem, the setup, and my code I used to solve the problem.  I will avoid explicitly stating the answer to the problem, because that defeats the purpose for those of you who haven't done PE.  I would also like to go into the theory, share anecdotes and derivations of formulae.  Actually, this section will most likely be the meat of the post, and what I will spend most of my time writing.  In the end, I want this blog will be less about the problems themselves than it is about the theory behind the problems.

About Project Euler:

Project Euler is a site for people who love to solve puzzles.  The puzzles range in difficulty from pretty gosh darn easy to graduate level mathematics.  Often times the problems will deal with special sequences of numbers, number theory, combinatorics, and linear algebra.  The problems are designed with a 1-minute rule.  That is, each solution should take less than one minute to complete.

The Project is named after one of the most prolific, and in my opinion, the greatest mathematician of all time, Leonhard Euler (Pronounced Oiler ).

According to Wikipedia, Project Euler was started in 2001 by Colin Hughs, since then the website has "gained notability and popularity worldwide."  On June 15th PE was temporarly shut down due to a security breach.  Shortly thereafter the site restarted in a stripped down state, as a read only website.

The Project Euler website is now back online in a limited fashion.  You can go there and look at the problems, and verify answers.  But there are no longer any badges and you can't keep any saved progress.  The owners of the website have said they plan on bringing the site back up to its full capacity soon though, just as soon as they work out the security issues.


About Me:

My name is Joseph Moore. I'm currently an undergraduate Computer Engineering major attending Northeastern University, and I have a passion for mathematics and computer science.  Years ago, I started programming with Python and have really grown to love the language and I am currently learning C.

My hobbies include running, reading, history, video games, especially Minecraft and Europa Universalis IV.  I'm currently working with a startup company based in Rochester as a summer intern.


Languages Used:

Pure Math:  In every area that is reasonable I will include a pure calculation, that is non-program assisted solution.  Some of the answers really are that easy to find, but not that many.

Python 3.4:  Keeping up to date with the latest version of python.  Code I may showcase from others might be based off of Python 2.x.  If it is too different from the counterpart in Python 3.x, I will provide an addition example.

C:  The lingua franca of the Linux/Unix community.  I'm still learning, so I don't know too much about it but feel free to point out how I could write it better.