The post Project Euler 1 Solution appeared first on Dreamshire.
]]>Project Euler 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.
This problem wants us to find the sum of all the natural numbers (positive integers) below 1000 that are evenly divided by 3, such as 3, 6, 9, … and 5, such as 5, 10, 15, …
This can be implemented quickly and intuitively by using an iterative approach that loops through a range of integers between 1 and 999. Using the mod operator to check for even divisibility (a 0 remainder after division) we sum those integers, i
, that are divisible by 3 or 5.
# single line using list comprehensions in python print sum(i for i in xrange(1, 1000) if i%3==0 or i%5==0) # a classical way in python s = 0 for i in xrange(1, 1000): if i%3==0 or i%5==0: s+= i print s
The program runs instantly for the less than 1000 limit but we quickly learn that this method does not scale to larger ranges such as 1 billion run 100,000 times is less than a second. Such is the demand required to be met by the HackerRank Project Euler 1. So we need to find a more efficient way of calculating this sum without looping.
There is a formula, attributed to Carl Friedrich Gauss, that will calculate the sum of the first n natural numbers and, by extension, the first nth natural numbers where nth will be 3 and 5 respectively.
For example, when n=10 the sum of all the natural numbers from 1 through 10 is: (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10) = 10*11 / 2 = 55.
Here’s how this formula works. Write the numbers in two rows that wrap around as shown below:
1 2 3 4 5
10 9 8 7 6
The sum of each column is 11 (i.e., n+1). As the top row increases, the bottom row decreases, so the column sum always stays the same and we’ll always have 2 rows and n/2 columns for any even number, n. If n is odd, start with zero instead of one.
which is the same formula as above.
We can adapt this formula to count the numbers only divisible by d to a specific limit; such as n=33, d=3, in the following example. Remember when there is an odd number we start from zero to keep the columns paired. Here’s how the adaptation works:
0 3 6 9 12 15
33 30 27 24 21 18
Each column sums to 33 and, using our understanding from above, we calculate 6*33 to find the sum of numbers to 33 that are evenly divisible by 3 (6*33=198). In the Python function sumn
this is accomplished by taking the floor of n divided by d to find the number of terms, then calculate the sum using the expanded formula below which accounts for the multiplier d.
By applying the above formula to n=999 and d=3 and d=5 we get the sums for every 3rd and 5th number. Adding those together is almost our answer but we must first subtract the sum of every 15th natural number (3 × 5) as it is counted twice: once in the 3 summation and once again in the 5 summation.
This is a typical application of the inclusion-exclusion principle. In general, sum the numbers less than 1000 that are divisible by 3 (3, 6, 9, 12, 15, …) or 5 (5, 10, 15, …) and subtract those divisible 3 and 5 (15, 30, 45, …).
This solution is much faster than using brute force which require loops, especially when the limit, L
, is large. Also note that we subtract 1 from the limit as the problem wants multiples below L
.
The sequence of numbers [1, 3, 6, 10, 15,…] are called the triangular numbers. The game of bowling or ten-pin sets 10 pins in a triangular form and thus uses the fourth number in this sequence. One pin in the first row and ending with 4 pins in the last row.
To calculate the Nth triangular number you add the first N numbers: 1 + 2 + 3 + … + N. If you want to find the 100th triangular number, you begin the long and laborious addition of the first 100 numbers.
Indeed, Gauss’s teacher liked to assign these kinds of problems to his class as it would keep them busy and quiet for some time. As each student finished the task they would place their slate tablets with their answer written on it in a pile in front of the teacher. While the other students began laboring away, the ten-year-old Gauss had laid his tablet on the table within seconds. Dubious, the teacher thought the young Gauss was being lazy. But when he looked at Gauss’s slate, there was the answer — 5,050 — with no steps in the calculation. The teacher thought that Gauss must have cheated somehow, but the pupil explained that all you needed to do was put N=100 into the formula 1/2 × (N + 1) × N and you will get the 100th number in the list without further additions.
Rather than tackling the problem head on, Gauss had thought geometrically. He argued that the best way to discover how many beans there were in a triangle with 100 rows was to take a second similar triangle of beans which could be placed upside down on top of the first triangle. Now Gauss had a rectangle with 101 rows each containing 100 beans. Calculating the number of beans in this rectangle built from the two triangles was easy: there are in total 101 × 100 = 10,100 beans. So one triangle must contain half this number, namely 1/2 × 101 × 100 = 5,050.
Example for 5 rows
x o x o o o o o
x x o o x x o o o o
x x x o o o —> x x x o o o
x x x x o o o o x x x x o o
x x x x x o o o o o x x x x x o
Project Euler 1
The post Project Euler 1 Solution appeared first on Dreamshire.
]]>The post Project Euler 10 Solution appeared first on Dreamshire.
]]>Project Euler 10: The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
This problem requires us to generate 2 million prime numbers, sum them and report their total. Using our prime number sieve introduced in problem 7 this is easy to solve in less than 100ms with a couple lines of Python:
from Euler import prime_sieve print sum(prime_sieve(2000000))
HackerRank asks a much more demanding question by having us solve up to 10,000 trials for any N≤1,000,000. Even though the prime number range is halved, it still requires both prime and non-prime queries up to N. This can be trickier than first thought and required a more utilitarian solution. Having the possibility of non-prime queries means that simply mapping prime numbers to sums won’t work in those cases, especially with the time restriction.
This solution sieves the primes and calculates a running sum concurrently before accepting any queries by filling a list (prime_sum
) with those sums. This allows each query to act as an index to the appropriate sum in the list.
prime_sieve
is listed in Common Functions and Routines for Project EulerThe post Project Euler 10 Solution appeared first on Dreamshire.
]]>The post Project Euler 100 Solution appeared first on Dreamshire.
]]>Project Euler 100: If a box contains twenty-one coloured discs, composed of fifteen blue discs and six red discs, and two discs were taken at random, it can be seen that the probability of taking two blue discs, P(BB) = (15/21)×(14/20) = 1/2.
The next such arrangement, for which there is exactly 50% chance of taking two blue discs at random, is a box containing eighty-five blue discs and thirty-five red discs.
By finding the first arrangement to contain over 10^{12} = 1,000,000,000,000 discs in total, determine the number of blue discs that the box would contain.
Given b=blue discs, n=total number of discs then the general equation is:
which is, in fact, a Diophantine Quadratic Equation and can be solved using a program provided on the following website: http://www.alpertron.com.ar/QUAD.HTM
Here is the input to the program for our equation:
[ 2] x^{2} +
[ 0] xy +
[-1] y^{2} +
[-2] x +
[ 1] y +
[ 0] = 0
Here is the output from the program:
2x^{2} – y^{2} – 2x + y = 0
X_{0} = 0
Y_{0} = 1
and also:
X_{0} = 1
Y_{0} = 1
X_{n+1} = 3X_{n} + 2Y_{n} – 2
Y_{n+1} = 4X_{n} + 3Y_{n} – 3
From here we have two equations that can calculate b and n for each term in the series. Instead of starting at b=1, n=1 we start with the values in the problem description to save a few iterations; b=85, n=120. We continue this series until n>10^{12}.
The equations are: blue disks = 3b + 2n – 2; n disks = 4b + 3n – 3 (also n = int(b/√2/2), but that’s another story).
The post Project Euler 100 Solution appeared first on Dreamshire.
]]>The post Project Euler 101 Solution appeared first on Dreamshire.
]]>If we are presented with the first k terms of a sequence it is impossible to say with certainty the value of the next term, as there are infinitely many polynomial functions that can model the sequence.
As an example, let us consider the sequence of cube numbers. This is defined by the generating function,
u_{n} = n^{3}: 1, 8, 27, 64, 125, 216, …
Suppose we were only given the first two terms of this sequence. Working on the principle that "simple is best" we should assume a linear relationship and predict the next term to be 15 (common difference 7). Even if we were presented with the first three terms, by the same principle of simplicity, a quadratic relationship should be assumed.
We shall define OP(k, n) to be the n^{th} term of the optimum polynomial generating function for the first k terms of a sequence. It should be clear that OP(k, n) will accurately generate the terms of the sequence for n ≤ k, and potentially the first incorrect term (FIT) will be OP(k, k+1); in which case we shall call it a bad OP (BOP).
As a basis, if we were only given the first term of sequence, it would be most sensible to assume constancy; that is, for n ≥ 2, OP(1, n) = u_{1}.
Hence we obtain the following OPs for the cubic sequence:
OP(1, n) = 1 | 1, 1, 1, 1, … |
OP(2, n) = 7n−6 | 1, 8, 15, … |
OP(3, n) = 6n^{2}−11n+6 | 1, 8, 27, 58, … |
OP(4, n) = n^{3} | 1, 8, 27, 64, 125, … |
Clearly no BOPs exist for k ≥ 4.
By considering the sum of FITs generated by the BOPs (indicated in red above), we obtain 1 + 15 + 58 = 74.
Consider the following tenth degree polynomial generating function:
u_{n} = 1 − n + n^{2} − n^{3} + n^{4} − n^{5} + n^{6} − n^{7} + n^{8} − n^{9} + n^{10}
Find the sum of FITs for the BOPs.
I used the difference method to solve this one as we only need to sum the FITs and not extend the series or find equations through fitting.
Take the example and build a pyramidal array with the base of k terms of the original expression. Next, take the differences between left-to-right neighbors and stack those differences on top of the base until the triangle is complete.
Now, sum the entire array to calculate the sum of all FITs. The individual FITs are summed along the diagonal layers of the triangle:
12 + 19 + 27 = 58, 7 + 8 = 15, 1
OP = n^{3}, k = 3
12 7 19 1 8 27
12 + 7 + 19 + 1 + 8 + 27 = 74
k, u = 3, lambda x: x**3 def tld(x): if len(x[-1]) == 1: return x return x + tld([[x[-1][i] - x[-1][i-1] for i in range(1, len(x[-1]))]]) print "Sum of FITs for the BOPs", sum(sum(tld([map(u, range(1, k+1))]), []))
The post Project Euler 101 Solution appeared first on Dreamshire.
]]>The post Project Euler 102 Solution appeared first on Dreamshire.
]]>Project Euler 102: Three distinct points are plotted at random on a Cartesian plane, for which -1000 ≤ x, y ≤ 1000, such that a triangle is formed.
Consider the following two triangles:
It can be verified that triangle ABC contains the origin, whereas triangle XYZ does not.
Using triangles.txt (right click and ‘Save Link/Target As…’), a 27K text file containing the co-ordinates of one thousand "random" triangles, find the number of triangles for which the interior contains the origin.
NOTE: The first two examples in the file represent the triangles in the example given above.
There are a few ways to solve this problem. With having the point to check be the origin (0,0), then the easiest way is to check that the signs of the cross products are all positive or negative. This solution could be easily modified to check points other than the origin.
The post Project Euler 102 Solution appeared first on Dreamshire.
]]>The post Project Euler 104 Solution appeared first on Dreamshire.
]]>The Fibonacci sequence is defined by the recurrence relation:
F_{n} = F_{n−1} + F_{n−2}, where F_{1} = 1 and F_{2} = 1.
It turns out that F_{541}, which contains 113 digits, is the first Fibonacci number for which the last nine digits are 1-9 pandigital (contain all the digits 1 to 9, but not necessarily in order). And F_{2749}, which contains 575 digits, is the first Fibonacci number for which the first nine digits are 1-9 pandigital.
Given that F_{k} is the first Fibonacci number for which the first nine digits AND the last nine digits are 1-9 pandigital, find k.
Even calculating the Fibonacci sequence without any optimization this solution was lightning fast. Getting the bottom 9 digits was easy and has been done in previous problems. The top 9 required the formula:
phi = (1 + sqrt(5)) / 2
t = n * log10(phi) + log10(1/sqrt(5))
t = int((pow(10, t – int(t) + 8)))
So, after finding a candidate with the bottom 9 digits pandigital we query the formula to see if the top 9 are pandigital. The first one found will be our first solution.
from Euler import is_pandigital
def top_digits(n):
t = n * 0.20898764024997873 + (-0.3494850021680094)
t = int((pow(10, t - int(t) + 8)))
return t
fk, f0, f1 = 2, 1, 1
while not is_pandigital(f1) or not is_pandigital(top_digits(fk)):
f0, f1 = f1, (f1+f0) % 10**9
fk += 1
print "Project Euler 104 Solution =", fk
Use this link to get the Project Euler 104 Solution Python 2.7 source.is_pandigital
is listed in Common Functions and Routines for Project EulerThe post Project Euler 104 Solution appeared first on Dreamshire.
]]>The post Project Euler 11 Solution appeared first on Dreamshire.
]]>Project Euler 11: In the 20×20 grid below, four numbers along a diagonal line have been marked in red.
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
…Data Continues…
The product of these numbers is 26 × 63 × 78 × 14 = 1788696.
What is the greatest product of four adjacent numbers in any direction (up, down, left, right, or diagonally) in the 20×20 grid?
The best way to solve this problem is to read the matrix into an array and iterate through the rows, columns and diagonals to find four adjacent cells that produce a maximum product. Only right, down, diagonal down-left and diagonal down-right need to be checked because of the commutative nature of multiplication.
This program assumes the same number of rows and columns. The data is saved to a file, pe11.txt in the
Trinket tab next to the main.py tab.
HackerRank makes no additional demands and just asks the same questions with the same parameters.
The post Project Euler 11 Solution appeared first on Dreamshire.
]]>The post Project Euler 112 Solution appeared first on Dreamshire.
]]>Working from left-to-right if no digit is exceeded by the digit to its left it is called an increasing number; for example, 134468.
Similarly if no digit is exceeded by the digit to its right it is called a decreasing number; for example, 66420.
We shall call a positive integer that is neither increasing nor decreasing a "bouncy" number; for example, 155349.
Clearly there cannot be any bouncy numbers below one-hundred, but just over half of the numbers below one-thousand (525) are bouncy. In fact, the least number for which the proportion of bouncy numbers first reaches 50% is 538.
Surprisingly, bouncy numbers become more and more common and by the time we reach 21780 the proportion of bouncy numbers is equal to 90%.
Find the least number for which the proportion of bouncy numbers is exactly 99%.
It was a surprise how long this program took to run. The is_bouncy() routine seemed to slow things down. We begin at the 90% point specified in the problem description and wait for the ratio to hit 99%.
def is_bouncy(n):
inc, dec, s = False, False, str(n)
for i in range(len(s)-1):
if s[i+1] > s[i]: inc = True
elif s[i+1] < s[i]: dec = True
if inc and dec: return True
return False
n, p = 21780, 0.90
b = n * p
while p != 0.99:
n += 1
if is_bouncy(n): b += 1
p = b / n
print "Project Euler 112 Solution =", n
Use this link to get the Project Euler 112 Solution Python 2.7 source.The post Project Euler 112 Solution appeared first on Dreamshire.
]]>The post Project Euler 113 Solution appeared first on Dreamshire.
]]>Working from left-to-right if no digit is exceeded by the digit to its left it is called an increasing number; for example, 134468.
Similarly if no digit is exceeded by the digit to its right it is called a decreasing number; for example, 66420.
We shall call a positive integer that is neither increasing nor decreasing a "bouncy" number; for example, 155349.
As n increases, the proportion of bouncy numbers below n increases such that there are only 12951 numbers below one-million that are not bouncy and only 277032 non-bouncy numbers below 10^{10}.
How many numbers below a googol (10^{100}) are not bouncy?
Whenever a problem asks for the number of elements in a set, as does this one, then the solution in typically a counting problem solved with combinometrics, dynamic programming or a generating function.
Our solution uses the general formula that counts the monotonically increasing/decreasing digits ignoring leading zeros.
To remove confusion surrounding the terms increasing and non-decreasing, Rudin, in his Principles of Mathematical Analysis (Def. 3.13), defines a sequence of real numbers to be:
(a) monotonically increasing if [i.e., non-decreasing].
(b) monotonically decreasing if [i.e., non-increasing].
To avoid ambiguity one can specify that a monotonic sequence is “strictly increasing” or that it is non-decreasing, or non-increasing, or strictly decreasing.
binomial
is listed in Common Functions and Routines for Project EulerThe post Project Euler 113 Solution appeared first on Dreamshire.
]]>The post Project Euler 114 Solution appeared first on Dreamshire.
]]>A row measuring seven units in length has red blocks with a minimum length of three units placed on it, such that any two red blocks (which are allowed to be different lengths) are separated by at least one black square. There are exactly seventeen ways of doing this.
How many ways can a row measuring fifty units in length be filled?
NOTE: Although the example above does not lend itself to the possibility, in general it is permitted to mix block sizes. For example, on a row measuring eight units in length you could use red (3), black (1), and red (4).
For the purpose of this discussion, the unit size of the space into which blocks (red) are placed is identified as n and the unit size of the red blocks, with a range in size from 3 to n, is identified as m. Also, an empty space void of any red blocks is counted.
This is a counting problem, so dynamic programming and its hand maiden linear programming come immediately to mind and usurp the notion of trying a brute-force solution.
And as far as examples go, 7 wasn’t the best choice as the problem admits, but it will suffice to answer the problem.
My first analogy was shifting groups of bits in a computer’s register, but here’s a more festive idea. I looked at this problem like a game of Tetris (Play a game online here). This is a much simpler version as there is only one dropping shape, a “line” with a minimum size of 3 units. Let’s look at the example graphic twisted slightly to show my thought process:
The only constraint is that no falling shapes can ever touch; they must be separated by at least one empty space.
As the red blocks fall the only variable is the length of the block, m; between 3 and 7. When we move to n = 8, this same configuration for n = 7 will be a subset of it. Just like n = 6 is a subset of n = 7.
In fact, to demonstrate this concept, lets try to calculate the number of ways we can fill 6 spaces:
How many survived the butchery? Change the variable n in the program to 6 and run it. Did it match your count?
By now, you could add a tile to our graphic and learn the count for 8 spaces. Soon a pattern would become obvious and a dynamic solution is born.
It’s just adding a series of numbers for each n as it increase from 3 through 50. Yes, a function (with binomial tendencies) exists out there that would always put to rest a dynamic programming solution for counting, but why spoil the fun.
from Euler import binomial as C n = 50 + 1 print sum(C(n - 2*k, 2*k) for k in range(int(n/4)+1))
The post Project Euler 114 Solution appeared first on Dreamshire.
]]>