Wednesday 17 February 2016

Project Euler #5: Smallest multiple

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?
 There's actually a really easy trick to solving this. It's not immediately obvious and I can't explain how it works well, but I'll do an example. Say we want the least common multiple of 1 through 10 (aka the smallest multiple). What we do is remove the prime factors from each of the numbers in order of smallest to lowest, but when take out a prime factor, we also remove it from any other number it can be removed from. For example
  • 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
  • Remove 2: 1, 1, 3, 2, 5, 3, 7, 4, 9, 5
  • Remove 3: 1, 1, 1, 2, 5, 1, 7, 4, 3, 5
  • Remove 2: 1, 1, 1, 1, 5, 1, 7, 2, 3, 5
  • Remove 5: 1, 1, 1, 1, 1, 1, 7, 2, 3, 1
  • Remove 7: 1, 1, 1, 1, 1, 1, 1, 2, 3, 1
  • Remove 2: 1, 1, 1, 1, 1, 1, 1, 1, 3, 1
  • Remove 3: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Now we multiply all the prime factors we extracted and that's our answer! So 2 x 2 x 2 x 3 x 3x 5 x 7 = 2520 as expected. Alternatively you could've also only factored the non-prime numbers, but that would require knowing which numbers are prime - which isn't immediately obvious at high values. You could also eliminate any number which already has a multiple of itself - so 1, 2, 3, 4, and 5 - if you wanted to. An alternate version can be found here.

Coding this was pretty simple and the runtime is under 10 microseconds for numbers 1 through 20. This is probably the fastest solution I can come up with. The brute force method takes about 3 seconds in comparison.

The code can be found here.

Friday 12 February 2016

Order of operations and overflow

Let's say you want 50% of 256 million (as in powers of two though like mebibytes, so 2 ^28). Easy, that's 128 million ( 2^27). One could easily write it out as
unsigned int elements = 256 * 1024 * 1024 * 50 * 0.01
You're multiplying 256 by 2^20 and by 0.5, which again equals 128 million. Not so fast! Because the operations happen from left to right, at one point you'll end up with a number that's over 13 billion (13,421,772,800 to be exact). Unsigned ints only go up to around 4 billion, so you'll overflow. The problem is you get an intermediate large number before your final answer. A safer approach is to be multiply the 0.01 before the 50 so you get a smaller intermediate number before your final answer. Yes, even though this is obvious, I still made this mistake.

Wednesday 10 February 2016

Project Euler #3: Largest prime factor


The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
I started off by recycling the code from PE-10. To find the largest prime factor I'm going to find ALL the prime factors. By finding them in increasing order, I'm guaranteed that the last one I find will be the largest prime factor (side note: this also works if the inputted number is a prime number since the factors are 1 and itself).

I begin by setting the limit to the inputted number and starting at 5 and repeating my earlier method to find prime numbers in increasing order (sieving on 2 and 3, then using the idea that the smallest prime factor must be less than or equal to the square root of the number being tested if it's NOT a prime number). For every prime number I test if it's a factor of the inputted number. If it isn't then I store it in my prime number vector and move on. However, if it is then I set the new limit to be the old limit divided by this prime factor. Then I repeat the process. I continue until I reach the limit.

This works only because I'm finding the prime factors in order. Once we find one, we know the next one must be greater or equal to the one we just found. Thus I can continue on in my for-loop, only having to retest the most recent prime number (e.g. 8 is 2x2x2) before moving on. I like this solution because the amount of numbers we test is quite low so it scales really well.

For example, this problem asked for the prime factors of 600851475143. The prime factors are:
  1. 71, new limit is 8462696833
  2. 839, new limit is 10086647
  3. 1471, new limit is 6857
  4. 6857, new limit is 6857 (since they're equal)
Once the latest prime factor equals the limit we know we're done! So we only had to test roughly ~1142 numbers (6857 / 6 since we sieved). I'm not sure if the runtime I measured using is accurate, but it's returning 502 microseconds. I didn't bother making a naive version for this one since I was lazy.

The code can be found here.

Wednesday 3 February 2016

Project Euler #1: Multiples of 3 and 5

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.

I'm feeling lazy so I'll do a quick post about the first problem since it's pretty straightforward. All I did was  loop through every number from 1 until the limit and test if either 3 or 5 was a divisor. Brute force ftw! Including the printing this takes 0.002 seconds.

Even still, I can think of a few things to speed it up if only trivially.
  1. Use something other than mod
  2. Instead of incrementing by 1, keep two counters - one for 3 and the other for 5. Increment whichever one is lower and add it to the sum until both counters reach the limit. This way you save on having to test if the number is a multiple of 3 or 5. You do however need to check if your two counters are equal. If they are then you skip that number.
The second solution might deserve to be coded for clarity if there's any interest. Be sure to check out the solution thread as there are some nice ways to get the answer without any coding.

Edit: The code is not formatted properly when embedded here for whatever reason