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 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 12 Solution appeared first on Dreamshire.
]]>Project Euler 12: The sequence of triangle numbers is generated by adding the natural numbers. So the 7^{th} triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …
Let us list the factors of the first seven triangle numbers:
We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
This problem sounds simple enough, but it is somewhat dastardly in getting results both quicky and correctly. The premise is to query triangular numbers (recall problem 1) and find the first one to have more than 500 divisors.
Our algorithm for solving this one was markedly improved by a detailed explanation provided by a Project Euler moderator named ‘rayfil’. Yet it still wasn’t fast enough to handle the more challenging hackerRank Project Euler 12 version with finding a triangle number with 1,000 divisors and 10 consecutive trials.
To solve, we sieve the number of divisors as we check each candidate for being a triangular number. The result was being able to solve for 5000 divisors in less than 10 seconds. Now, one may question the somewhat arbitrary value for n=4200
. It’s a cap on the potential triangular number index search used to tune the algorithm for performance. It could be set to some other high value to accommodate deeper investigations.
The post Project Euler 12 Solution appeared first on Dreamshire.
]]>The post Project Euler 13 Solution appeared first on Dreamshire.
]]>Project Euler 13: Work out the first ten digits of the sum of the following one-hundred 50-digit numbers.
This problem requires us to find the first 10 (leftmost) digits of the sum of one hundred 50-digit integers.
The numbers were saved to a file named pe13.txt (second Trinket tab next to the main.py tab). This keeps the data and the program separate and the process easy to comprehend.
The file is read as strings and converted to a list of integers using the map
function with open
as the iterator and int
as the application function: sum(map(int, open('pe13.txt')))
. After the end of the file is reached the list is fed to the sum
function which adds the integers together: sum(map(int, open('pe13.txt')))
. This integer sum is finally converted to a string str(total)[:10] and truncated to the top 10 digits for a solution: str(total)[:10].
HackerRank increases the data set from 100 to 1000 numbers. Same solution.
print "Top 10 digits of sum =", str(sum(map(int, open('pe13.txt'))))[:10]
Have a great day – and check out some of my other pages.
Thanks,
your friend,
Mike
June 8, 2014
The post Project Euler 13 Solution appeared first on Dreamshire.
]]>The post Project Euler 14 Solution appeared first on Dreamshire.
]]>Project Euler 14: The following iterative sequence is defined for the set of positive integers:
n → n/2 (n is even)
n → 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
The Python program listed in the Afterthoughts section shows the hailstone
calculator for determining values in the Collatz chain for a number, N. The d
function determines the length of the chain and the purpose of the program is to determine the longest length for a set of consecutive numbers below some limit, L
. It became apparent that the lengths were simply a collection of discrete points over the domain.
So, when challenged by HackerRank Project Euler 14 with more aggressive limits (N<=10,000,000), and running thousands of trials in fewer than 5 seconds it became obvious that building a table was the best way to go.
There are fragments of this sequence in the OEIS but a problem was the requirement to find the maximum starting value when the same chain length is shared by other starting numbers.
For example 35497 is not found in these on-line sequences and for an N=34555 the starting number for the longest chain returned is 34239. Well it seems the 35497 shares the same number of terms and is the greater of the two. 35497 is the correct response.
This required going backwards through a range of numbers (say 10^{7}) and finding the stopping points and taking these maximums into consideration. That result is the list shown in the Python source code below.
c = [1, 2, 3, 6, 7, 9, 18, 19, 25, 27, 54, 55, 73, 97, 129, 171, 231, 235, 313, 327, 649, 654,
655, 667, 703, 871, 1161, 2223, 2322, 2323, 2463, 2919, 3711, 6171, 10971, 13255, 17647,
17673, 23529, 26623, 34239, 35497, 35655, 52527, 77031, 106239, 142587, 156159, 216367,
230631, 410011, 511935, 626331, 837799, 1117065, 1126015, 1501353, 1564063, 1723519,
2298025, 3064033, 3542887, 3732423, 5649499, 6649279, 8400511, 11200681]
L = 1000000
print min(c[::-1], key=lambda x: x>L)
Use this link to get the Project Euler 14 Solution Python 2.7 source.L = 1000000
hailstone = lambda n: 3*n + 1 if n%2 else n//2
def d(n, _={1:1}):
if n not in _: _[n] = d(hailstone(n)) + 1
return _[n]
print max(range(1, L), key=d)
The post Project Euler 14 Solution appeared first on Dreamshire.
]]>The post Project Euler 15 Solution appeared first on Dreamshire.
]]>Project Euler 15: Starting in the top left corner of a 2×2 grid, there are 6 routes (without backtracking) to the bottom right corner.
How many routes are there through a 20×20 grid?
This question has been posed as: “Starting at the top left corner, how many ways through town are possible using only one-way streets and ending at the bottom right corner of a n x n grid?”
Another analogy might be: “Place a single rook on the top left corner of an empty chess board and count the number of tours to the bottom right corner moving only left and down.” This would assume an 8 × 8 grid.
This solution extends to solving n × m grids as well as the n × n grid by using a simple combination calculation. For example, the valid paths for a 2 × 2 grid shown in the example are the discreet (unique) permutations of {R, R, D, D}. We can list these as: {R, R, D, D}, {R, D, R, D}, {R, D, D, R}, {D, R, R, D}, {D, R, D, R}, and {D, D, R, R}. You must have n Rs (rights) and n Ds (downs) the order not being important and as long as you start from the top-left corner you will always end at the bottom-right corner.
For a 4 × 4 grid it would be the discreet permutations of {R, R, R, R, D, D, D, D} where any combination or 4 Rs and 4 Ds will always be a valid path. If the Rs are place randomly in 4 of the 8 slots first they can be considered independent and the Ds would be considered dependent because they have to be placed into the remaining open slots.
For example, placing the 4 Rs randomly in any of the available 8 slots as {R, _, R, R, _, R, _, _} will dictate where the Ds get placed as {R, D, R, R, D, R, D, D}. You end up with just _{8}C_{4} = 70 valid combinations.
It could also be described as how many distinct ways can you shuffle the characters in the string “RRRRDDDD”.
Continuing our thinking from above we realize that determining the number of contiguous routes for a square grid (n × n) is the central binomial coefficient or the center number in the 2n^{th} row of Pascal's triangle. The rows start their numbering at 0.
The formula in general for any rectangular grid (n × m) using the notation for the binomial coefficient is:
The post Project Euler 15 Solution appeared first on Dreamshire.
]]>The post Project Euler 16 Solution appeared first on Dreamshire.
]]>Project Euler 16: 2^{15} = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 2^{1000}?
We are asked to calculate a very large power of 2 and sum the individual digits of the result. As Python natively supports arbitrary precision integers, with millions of digits if necessary, it makes this task easy to do.
We calculate 2^{1000} and convert the result to a string: sum(map(int, str(pow(2, 1000))))
. Next, using the map
function with the result string at the iterator and int
as the application function we split the digits of the result into individual characters and convert to integers: sum(map(int, str(pow(2, 1000))))
. The sum of the digits is calculated by the sum
function as the answer to the problem: sum(map(int, str(pow(2, 1000))))
.
The HackerRank Project Euler 16 version increases the exponent to 10,000 and runs a hundred trials in a few milliseconds. Same solution.
The post Project Euler 16 Solution appeared first on Dreamshire.
]]>The post Project Euler 17 Solution appeared first on Dreamshire.
]]>Project Euler 17: If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of “and” when writing out numbers is in compliance with British usage.
This version will deviate somewhat from the specified requirements and instead write out the numbers to 1 trillion as is required by the HackerRank Project Euler 17 version. The intention of the original Project Euler problem was to verify, somewhat, that the numbers were converted properly and uses a character count to verify a correct result.
Given that there is no other way of verifying that every number was correctly converted to words this is an OK compromise, but having a program that reliably translates numbers to words seems much more valuable. Such as spelling out monetary amounts on checks.
The grouping of the number into three digit groups is accomplished by the following line:
number = map(''.join, zip(*[iter(str(n).zfill(len(thousands)*3))]*3))
The intention is to always have a fully qualified number with leading zeros. For example, with the maximum thousands
of ‘Quadrillion’ or 10^{15}, 34,509 will become 000 000 000 000 034 509 (spaces added for readability).
Next, a Python idiom for clustering a data series into n-length groups using zip(*[iter(s)]*n)
, is applied to the zero-filled number. The final list named number
is compiled by the map/join
functions as: ['000', '000', '000', '000', '034', '509']
. The ‘000’ groups are ignored during processing.
Dashes can be added by including a dash at the end of each tens
list element other than ‘ten’. The extra spaces would have to be removed as changing ‘- ‘ to ‘-‘.
Likewise, a single ‘and’ could also be included after the thousands/hundreds group when the last group is less than 100.
The program is able to be expanded to include other thousand groups by adding the group name onto the code>thousands list if 999 quadrillion is not enough. I have no idea why, except for a projected U.S. deficit.
The post Project Euler 17 Solution appeared first on Dreamshire.
]]>The post Project Euler 18 Solution appeared first on Dreamshire.
]]>Project Euler 18: By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.
3
7 5
2 4 6
8 5 9 3
That is, 3 + 7 + 4 + 9 = 23.
Find the maximum total from top to bottom of the triangle below:
75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
… {data continues} …
NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)
To solve this problem and problem 67, which is much larger, start the search from the bottom to the top, adding the maximums along the way. This will “bubble” the maximum total to the top of the pyramid.
Let’s follow this technique, step-by-step, with the 4 row triangle example above to show how this works.
3
7 5
2 4 6
8 5 9 3
Starting at the bottom,
We look at 8 and 5, pick the maximum, 8 in this case, and replace the 2 in the previous row with their sum 10.
We look next at 5 and 9, pick the maximum, 9, and replace the 4 in the previous row with their sum 13.
We look lastly at 9 and 3, pick the maximum, 9, and replace the 6 in the previous row with their sum 15.
Now our array looks like:
3
7 5
10 13 15
Let’s do it again. Take the larger of 10 and 13 and add it to 7 making 20.
Take the larger of 13 and 15 and add it to 5 making 20.
Now our array looks like:
3
20 20
At last we take the larger of 20 and 20 (yes, I know they’re the same) and add it to 3 making 23.
And our array looks like:
23
The maximum total path in the triangle.
HackerRank doesn’t add more to the challenge other than running 10 trials. The data for this problem is kept in the second Trinket tab named pe18.txt, next to the main.py tab.
table
.Project Euler 18
The post Project Euler 18 Solution appeared first on Dreamshire.
]]>The post Project Euler 19 Solution appeared first on Dreamshire.
]]>Project Euler 19: You are given the following information, but you may prefer to do some research for yourself.
1 Jan 1900 was a Monday.
Thirty days has September,
April, June and November.
All the rest have thirty-one,
Saving February alone,
Which has twenty-eight, rain or shine.
And on leap years, twenty-nine.
A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?
The problem provides two dates, let’s call them a and b, where a≤b chronologically, and we are challenged to find the number of Sundays that occur on the first of the month within the date range, inclusively. This particular exercise has the date range fixed at 1/1/1901 and 12/31/2000.
Our solution was extended to allow any date range, any weekday and any day of the month and calculate the number of times that weekday lands on that day of the month.
There are 1200 months (therefore 1200 firsts of the month) in 100 years (1/1/1901 – 12/31/2000). One in every 7 days is a Sunday which is (roughly) uniformly distributed over the date range. An estimate of 1200/7 Sundays should be close to the answer. As the date range widens this estimate becomes less precise.
The Python program below leverages the datetime
library and starts by initializing some parameters:
dD
| A timedelta of one day. By adding this to a date object the date is incremented by 1 day. |
c
| A counter to tally matches. |
dowx
| The Python datetime weekday numeric representation as: 0 for Monday, 1 for Tuesday, …, 6 as Sunday. |
datex
| The day of the month, 1-31, that must coincide with the weekday. |
Y1, M1, D1
| Year, month, day. The beginning of the inclusive date range. |
Y2, M2, D2
| Year, month, day. The end of the inclusive date range. |
import datetime as dt dD, c, dowx, datex = dt.timedelta(days=1), 0, 6, 1 Y1, M1, D1, Y2, M2, D2 = 1901,1,1, 2000,12,31
We need two parameters before we start our search. Firstly, because HackerRank Project Euler 19 can specify a year with 17 digits we will need to determine the number of years in the range. Secondly, we must normalize the years (Y1
and Y2
) to bring it within the acceptable year values of the datetime
library.
dY = Y2-Y1 #number of years Y1 = (Y1%400) + 400 #normalized and non-zero
The calendar completes a full cycle every 400 years, so 2016 and 2416 will use the same calendar. If you don't cross a century, such as 1900 then the calendar repeats every 28 years, so 1916 and 1944 will share the same calendar. However, 1886 and 1914, although 28 years apart, will not because they cross the century 1900 which is not a leap year.
An exception to this rule is when a century is evenly divisible by 400, such as the year 2000, then you can safely add 28 years across those centuries to get identical calendars. For example, 1986 and 2014 are 28 years apart and share the same calendar.
To find the number of Sundays on the 1st of the month within the inclusive date range we cycle through the years, day-by-day, until we find our first match. Then we continue our search week-by-week counting matches in our date range; this optimizes the search. If you wondered why we didn't just cycle by months, then you have yet to realize the limits of the datetime
library. dateutil
is an extension to the standard Python package that offers more capability, but was unused for this exercise.
a = dt.datetime(Y1, M1, D1) b = dt.datetime(Y1+dY, M2, D2) while a <= b: if a.day==datex and a.weekday()==dowx: c+= 1; dD=dt.timedelta(days=7) a += dD
Here's a site for generating calendars for any year: Calendar home
Read more: Patterns in the Perpetual Calendar
Also, some think that using date or calendar libraries is taking unfair advantage when solving these kind of problems. Nothing could be further from the truth. You need to leverage well vetted software in order to speed development time and reduce errors. Using established extensions and packages is simply good practice.
The post Project Euler 19 Solution appeared first on Dreamshire.
]]>