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 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.
]]>The post Project Euler 115 Solution appeared first on Dreamshire.
]]>NOTE: This is a more difficult version of Problem 114.
A row measuring n units in length has red blocks with a minimum length of m 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.
Let the fill-count function, F(m, n), represent the number of ways that a row can be filled.
For example, F(3, 29) = 673135 and F(3, 30) = 1089155.
That is, for m = 3, it can be seen that n = 30 is the smallest value for which the fill-count function first exceeds one million.
In the same way, for m = 10, it can be verified that F(10, 56) = 880711 and F(10, 57) = 1148904, so n = 57 is the least value for which the fill-count function first exceeds one million.
For m = 50, find the least value of n for which the fill-count function first exceeds one million.
This problem could easily be solved by playing with the interactive solution on the Problem 114 page. Just change m to 50 and play with n until it first exceeeds one million. The value of n won’t be very big because we start m at 50.
Again, i opted out of a recursive solution or generating functions because, after a while, dynamic programming becomes so intuitive for solving counting problems.
Also, I didn’t bother with an F()
function as I wanted to simply make a few changes to the previous problem and finish it. Instead of a fixed-size array, I dynamically increase it as necessary since I have no clue as to how big it should be to start with.
Well, actually, I do have a clue, but not if the parameters of this problem were changed.
The post Project Euler 115 Solution appeared first on Dreamshire.
]]>The post Project Euler 116 Solution appeared first on Dreamshire.
]]>A row of five black square tiles is to have a number of its tiles replaced with coloured oblong tiles chosen from red (length two), green (length three), or blue (length four).
If red tiles are chosen there are exactly seven ways this can be done.
If green tiles are chosen there are three ways.
And if blue tiles are chosen there are two ways.
Assuming that colours cannot be mixed there are 7 + 3 + 2 = 12 ways of replacing the black tiles in a row measuring five units in length.
How many different ways can the black tiles in a row measuring fifty units in length be replaced if colours cannot be mixed and at least one coloured tile must be used?
NOTE: This is related to Problem 117.
As a continuation from the two previous problems we remove the empty space option and one-space tile separation requirement. Now it makes sense to include a function since we are adding 3 different fixed-length tiles of sizes 2, 3 and 4.
The post Project Euler 116 Solution appeared first on Dreamshire.
]]>The post Project Euler 117 Solution appeared first on Dreamshire.
]]>Using a combination of black square tiles and oblong tiles chosen from: red tiles measuring two units, green tiles measuring three units, and blue tiles measuring four units, it is possible to tile a row measuring five units in length in exactly fifteen different ways.
How many ways can a row measuring fifty units in length be tiled?
NOTE: This is related to Problem 116.
As the simplest solution for the problem set requium, we make a small change to problem 116 by allowing multiple tiles of length 2, 3 and 4 to share the space.
The post Project Euler 117 Solution appeared first on Dreamshire.
]]>The post Project Euler 119 Solution appeared first on Dreamshire.
]]>The number 512 is interesting because it is equal to the sum of its digits raised to some power: 5 + 1 + 2 = 8, and 8^{3} = 512. Another example of a number with this property is 614656 = 28^{4}.
We shall define a_{n} to be the nth term of this sequence and insist that a number must contain at least two digits to have a sum.
You are given that a_{2} = 512 and a_{10} = 614656.
Find a_{30}.
Taking advantage of the easy large integer support in Python, we iterated two loops representing the base and exponent with the intention of accommodating inquiries up to a_{200}. Ignoring a^{b} values < 10 it was a simple process of adding the digits of the powers and comparing that sum to the base. After collecting relevant values into an array, it was sorted and the proper index printed for the answer.
def sum_of_digits(n):
return sum(map(int, str(n)))
a = []
n = 30
for b in range(2, 100):
for e in range(2, 10):
p = b ** e
if sum_of_digits(p) == b: a.append(p)
a.sort()
print "Answer to PE119 = a(%d) =" % n, a[n-1]
Use this link to get the Project Euler 119 Solution Python 2.7 source.The post Project Euler 119 Solution appeared first on Dreamshire.
]]>