The post Project Euler 93 Solution appeared first on Dreamshire.
]]>By using each of the digits from the set, {1, 2, 3, 4}, exactly once, and making use of the four arithmetic operations (+, −, *, /) and brackets/parentheses, it is possible to form different positive integer targets.
For example,
8 = (4 * (1 + 3)) / 2
14 = 4 * (3 + 1 / 2)
19 = 4 * (2 + 3) − 1
36 = 3 * 4 * (2 + 1)
Note that concatenations of the digits, like 12 + 34, are not allowed.
Using the set, {1, 2, 3, 4}, it is possible to obtain thirty-one different target numbers of which 36 is the maximum, and each of the numbers 1 to 28 can be obtained before encountering the first non-expressible number.
Find the set of four distinct digits, a < b < c < d, for which the longest set of consecutive positive integers, 1 to n, can be obtained, giving your answer as a string: abcd.
Well, this is just a complicated conglomeration of combinations, permutations and products of expressions that quickly finds a maximum sequence size and the associated terms that yield that maximum.
1. Define combinations of terms using the integers from 1 to 9. There aren’t that many, just 126 sets from (1,2,3,4) to (6, 7, 8, 9).
2. Permute each combination. (1,2,3,4), (1,2,4,3), (1,4,2,3), etc.
3. Create an iterator of operators using the product method that look like (+++, ++*, ++-, ++/, +*+, etc.) and calculate each expression in such a way that we avoid a div by zero. Oh, BTW, use truediv instead of div, that cost me some time not knowing the difference.
4. Collect a maximum sequence size, and sequence length.
5. Fin. This was a bit difficult to get my head around at first, but just stated coding and it fell together. Yeah, there are only two equations required – not five. Graph the possibilities and check out the relationship between nodes. This works perfectly to solve this problem.
from operator import add, sub, mul, truediv
import itertools
def seq_length(s, c=1):
while c in s: c+= 1
return c-1
maxt, maxs = 0, 0
for terms in itertools.combinations(range(1, 10), 4):
s = set()
for n in itertools.permutations(terms):
for op in itertools.product([add, mul, sub, truediv], repeat=3):
x = op[0](op[1](n[0],n[1]),op[2](n[2],n[3])) # (a.b).(c.d)
if x%1 == 0 and x > 0: s.add(int(x))
x = op[0](op[1](op[2](n[0],n[1]),n[2]),n[3]) # ((a.b).c).d
if x%1 == 0 and x > 0: s.add(int(x))
if seq_length(s) > maxs: maxs, maxt = seq_length(s), terms
print "Terms that produce longest set of consecutive digits", ''.join(str(i) for i in maxt)
Use this link to get the Project Euler 93 Solution Python 2.7 source.The post Project Euler 93 Solution appeared first on Dreamshire.
]]>The post Project Euler 98 Solution appeared first on Dreamshire.
]]>By replacing each of the letters in the word CARE with 1, 2, 9, and 6 respectively, we form a square number: 1296 = 36^{2}. What is remarkable is that, by using the same digital substitutions, the anagram, RACE, also forms a square number: 9216 = 96^{2}. We shall call CARE (and RACE) a square anagram word pair and specify further that leading zeroes are not permitted, neither may a different letter have the same digital value as another letter.
Using words.txt (right click and ‘Save Link/Target As…’), a 16K text file containing nearly two-thousand common English words, find all the square anagram word pairs (a palindromic word is NOT considered to be an anagram of itself).
What is the largest square number formed by any member of such a pair?
NOTE: All anagrams formed must be contained in the given text file.
A simple and straightforward implementation that performs as follows:
1. Read words into a list from network resource. Trim first and last quote characters.
2. Build anagram word pair list for those words > 4 letters. Clearly, 3 and fewer letter words are non-contenders, nor are 4 letter words. We are given 96^{2}, and 97^{2}, 98^{2}, and 99^{2} wouldn’t work because they repeat a digit or contain the dreaded zero and unable to leave a maximum greater than the given 9216.
3. Find all combinations of values using the pattern set in word’s anagram. You could check duplicate patterns for the same words size and ignore those, but I didn’t do that. Also note that I’m convinced zero will never be a factor.
4. Collect maximum square values for an ultimate global maximum.
5. Fin. Print the maximum.
import urllib2, itertools
def sq(n):
x = int(''.join(y[letter_set[i]] for i in n))
return x if int(x**0.5)**2 == x else False
file_url = "https://projecteuler.net/project/resources/p098_words.txt"
words = [w[1:-1] for w in urllib2.urlopen(file_url).read().split(',')]
word_pairs = []
while words:
w = words.pop()
if len(w) > 4:
x = sorted(w)
word_pairs+= ((w, a) for a in words if sorted(a) == x)
max_sq = 0
for w, a in word_pairs:
letter_set = {x:y for y, x in enumerate(set(w))}
for y in itertools.permutations('123456789', len(letter_set)):
if sq(w) and sq(a): max_sq = max(sq(w), sq(a), max_sq)
print "Largest square formed by any member of an anagram set:", max_sq
Use this link to get the Project Euler 98 Solution Python 2.7 source.The post Project Euler 98 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 83 Solution appeared first on Dreamshire.
]]>NOTE: This problem is a significantly more challenging version of Problem 81.
In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by moving left, right, up, and down, is indicated in bold red and is equal to 2297.
131 | 673 | 234 | 103 | 18 |
201 | 96 | 342 | 965 | 150 |
630 | 803 | 746 | 422 | 111 |
537 | 699 | 497 | 121 | 956 |
805 | 732 | 524 | 37 | 331 |
Find the minimal path sum, in matrix.txt (right click and “Save Link/Target As…”), a 31K text file containing a 80 by 80 matrix, from the top left to the bottom right by moving left, right, up, and down.
This problem is more complex than problems 81 and 82. We are still trying to find a minimum path sum from the top-right corner to the bottom-left corner but are now allowed to move left in addition to up, down and right. This rules out a dynamic approach as we cannot look left.
Fortunately, we have a great package for Python call networkx. It allows us to build a directed graph of the matrix and specify a start location (source=(0,0)), a target location (target=(n-1,m-1)) and a method for solving (A-star or Dijkstra). The directions are up(-1,0), down(+1,0), right(0,+1) and left(0,-1) when valid.
Our solution is now reduced to:
We read the data into a matrix from a URL resource as before and build a simple graph. The neighbors
array is a device to list the neighbors for each cell and exclude any that lie outside the matrix. Edges are added for each cell with the contents used as a weight.
All thatâ€™s left is to send it to the package and await the result.
import networkx as nx
from urllib2 import urlopen
file_url = 'https://projecteuler.net/project/resources/p082_matrix.txt'
matrix = [map(int, row.split(',')) for row in urlopen(file_url).readlines()]
n, m = len(matrix), len(matrix[0])
G = nx.DiGraph()
for i in xrange(n):
for j in xrange(m):
neighbors = [(i+x, j+y) for x, y in (-1,0), (0,-1), (1,0), (0,1)
if 0 <= i+x < n and 0 <= j+y < m]
for ix, jy in neighbors:
G.add_edge((i, j), (ix, jy), weight = matrix[ix][jy])
path_length = nx.dijkstra_path_length(G, source=(0,0), target=(n-1,m-1))
print "Minimum path sum in", n, "by", m, "matrix =", path_length + matrix[0][0]
Use this link to get the Project Euler 83 Solution Python 2.7 source.The post Project Euler 83 Solution appeared first on Dreamshire.
]]>The post Project Euler 128 Solution appeared first on Dreamshire.
]]>A hexagonal tile with number 1 is surrounded by a ring of six hexagonal tiles, starting at "12 o’clock" and numbering the tiles 2 to 7 in an anti-clockwise direction.
New rings are added in the same fashion, with the next rings being numbered 8 to 19, 20 to 37, 38 to 61, and so on. The diagram below shows the first three rings.
By finding the difference between tile n and each its six neighbours we shall define PD(n) to be the number of those differences which are prime.
For example, working clockwise around tile 8 the differences are 12, 29, 11, 6, 1, and 13. So PD(8) = 3.
In the same way, the differences around tile 17 are 1, 17, 16, 1, 11, and 10, hence PD(17) = 2.
It can be shown that the maximum value of PD(n) is 3.
If all of the tiles for which PD(n) = 3 are listed in ascending order to form a sequence, the 10th tile would be 271.
Find the 2000th tile in this sequence.
This is a modified version of the solution for probelm 58 – The square spiral – as this is a hex spiral constructed in the same way. As you may have guessed, just like ignoring the bottom-right diagonal in the square spiral, there are many directions we can ignore here as well as they always yield a non-prime difference (both even or both odd).
The solution below is a first swing at finding a solution. The real task is to learn of the generating function that will replace this brute force search.
from Euler import is_prime
def tiles(L=2000):
n, c = 1, 1
while c <= L:
r = 6 * n
if is_prime(r-1):
if is_prime(r+1) and is_prime(2*r+5): c += 1
if is_prime(r+5) and is_prime(2*r-7): c += 1
n += 1
return n-1
n = tiles()
print 3*n*(n - 1) + 2 if is_prime(6*n+1) else 3*n*(n + 1) + 1
Use this link to get the Project Euler 128 Solution Python 2.7 source.The post Project Euler 128 Solution appeared first on Dreamshire.
]]>The post Project Euler 94 Solution appeared first on Dreamshire.
]]>It is easily proved that no equilateral triangle exists with integral length sides and integral area. However, the almost equilateral triangle 5-5-6 has an area of 12 square units.
We shall define an almost equilateral triangle to be a triangle for which two sides are equal and the third differs by no more than one unit.
Find the sum of the perimeters of all almost equilateral triangles with integral side lengths and area and whose perimeters do not exceed one billion (1,000,000,000).
A good magic trick seems to defy both logic and physics until the secret is revealed. Then your response is something like: “What? That’s it! You just stacked the deck? I can’t believe I fell for that!” But until that point you were truly impressed.
Such are the secrets of these infernal math problems. I usually have few clues knowing where to begin and after some research and study I hack together a few short lines of code and wonder: “How is it I didn’t see that two hours ago?”
Anyway, here’s the solution to this problem of isoscele triangles trying to masquerade as “almost equilaterals.” Resources include Wikipedia’s article Almost-equilateral Heronian triangles, the series Reference: The On-Line Encyclopedia of Integer Sequences (OEIS) : Areas of 'close-to-equilateral' integer triangles, and the table below in the comments section which yields some evidence of a sequence and the recurrence equation wrapped in a Diophantine equation that guarantee integer results.
Adding ±1 to the perimeter guarantees an even area and perimeter as the problem requires.
Side 1 (a) | Side 2 (a) | Side 3 (b=a±1) | Perimeter | Area |
---|---|---|---|---|
5 | 5 | 6 | 16 | 12 |
17 | 17 | 16 | 50 | 120 |
65 | 65 | 66 | 196 | 1848 |
241 | 241 | 240 | 722 | 25080 |
901 | 901 | 902 | 2704 | 351780 |
3361 | 3361 | 3360 | 10082 | 4890480 |
12545 | 12545 | 12546 | 37636 | 68149872 |
46817 | 46817 | 46816 | 140450 | 949077360 |
174725 | 174725 | 174726 | 524176 | 13219419708 |
652081 | 652081 | 652080 | 1956242 | 184120982760 |
2433601 | 2433601 | 2433602 | 7300804 | 2564481115560 |
9082321 | 9082321 | 9082320 | 27246962 | 35718589344360 |
33895685 | 33895685 | 33895686 | 101687056 | 497495864091732 |
126500417 | 126500417 | 126500416 | 379501250 | 6929223155685600 |
The post Project Euler 94 Solution appeared first on Dreamshire.
]]>The post Project Euler 123 Solution appeared first on Dreamshire.
]]>Let p_{n} be the nth prime: 2, 3, 5, 7, 11, …, and let r be the remainder when (p_{n}−1)^{n} + (p_{n}+1)^{n} is divided by p_{n}^{2}.
For example, when n = 3, p_{3} = 5, and 4^{3} + 6^{3} = 280 ≡ 5 mod 25.
The least value of n for which the remainder first exceeds 10^{9} is 7037.
Find the least value of n for which the remainder first exceeds 10^{10}.
Using much of our understanding from solving Problem 120, we are able to easily adapt those methods to solve this problem. The differences are as follows:
We can make an educated guess of how many primes we’ll need by applying the remainder formula to a sufficiently large prime number and check that the results exceeds our target I (10^{10} in this case). So, I guessed by using a list of primes at the 22044^{th} prime number 249,989 with a remainder of 2*22044*249989 = 11021515032. That’s greater then 10^{10} and will suffice.
from Euler import prime_sieve
def pe123(L=10**10, ni=7039):
primes = [0] + prime_sieve(250000) # base prime number array from one
for n in range(ni, len(primes), 2):
if 2 * n * primes[n] > L:
return n
return None
print "First n for remainder to exceed limit:", pe123()
Use this link to get the Project Euler 123 Solution Python 2.7 source.The post Project Euler 123 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 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 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.
]]>