Solved 37 and added 38,39 problem statements.

main
Felix Martin 2018-05-13 11:56:15 -04:00
parent 000d770b81
commit 50290101b4
8 changed files with 1722 additions and 2 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,11 +4,306 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Euler Problem 37"
"# Euler Problem 37\n",
"\n",
"The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.\n",
"\n",
"Find the sum of the only eleven primes that are both truncatable from left to right and right to left.\n",
"\n",
"NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Okay, I would say we start with one digit and work ourselves up. I will start with implementing a function that takes all current solutions (with one digit for example) and then tests all possible new solutions (aka all two digit primes) if the can be truncated to the one digit solutions.\n",
"\n",
"This was complicated. Let's formulate it clearer. We write a function that takes a list of numbers and tests whether they are left/right trunctable to another list of numbers."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def get_truncatable_numbers(numbers, targets):\n",
" s = set(targets)\n",
" r = []\n",
" for n in numbers:\n",
" left_trunc = int(str(n)[1:])\n",
" right_trunc = int(str(n)[:-1])\n",
" if left_trunc in s and right_trunc in s:\n",
" r.append(n)\n",
" return r\n",
"\n",
"assert(get_truncatable_numbers([37, 77, 83], [2, 3, 5, 7]) == [37, 77])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The next function returns a list of all primes with a certain number of digits n. We gonna reuse the sieve from problem 21."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def sieve_of_eratosthenes(limit):\n",
" primes = []\n",
" prospects = [n for n in range(2, limit)]\n",
" while prospects:\n",
" p = prospects[0]\n",
" prospects = [x for x in prospects if x % p != 0]\n",
" primes.append(p)\n",
" if p * p > limit:\n",
" break\n",
" primes += prospects\n",
" return primes\n",
"\n",
"\n",
"def get_primes_with_n_digits(n):\n",
" lower_limit = 10**(n-1) - 1\n",
" upper_limit = 10**n\n",
" primes = sieve_of_eratosthenes(upper_limit)\n",
" primes = [p for p in primes if p > lower_limit]\n",
" return primes\n",
" \n",
"assert(get_primes_with_n_digits(1) == [2, 3, 5, 7])\n",
"assert(len(get_primes_with_n_digits(2)) == 21)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we simply start with all one digit primes and work our way up using the two functions we have created. On the way up we add the numbers to our result list. For example, 97 is already a valid solution even though it is also the subset of a solution with more digits."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[23, 37, 53, 73, 373]\n"
]
}
],
"source": [
"digits = 1\n",
"solutions = get_primes_with_n_digits(digits)\n",
"results = []\n",
"\n",
"while solutions:\n",
" digits += 1\n",
" solutions = get_truncatable_numbers(get_primes_with_n_digits(digits), solutions)\n",
" for s in solutions:\n",
" results.append(s)\n",
" \n",
"print(results)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This are not the eleven numbers we are looking for. The mistake we made is to not differentiate between left truncatable numbers and right truncatable numbers. For example, 397 is truncatable from the left, but not from the right and is still part of a solution. What we want to do is to work up from both directions and then compute the subset. Hence we write to new functions to check for all truncatable numbers from either left or right and then apply the algorithm from above to both of them."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def get_truncatable_numbers_right(numbers, targets):\n",
" s = set(targets)\n",
" return [n for n in numbers if int(str(n)[:-1]) in s]\n",
"\n",
"def get_truncatable_numbers_left(numbers, targets):\n",
" s = set(targets)\n",
" return [n for n in numbers if int(str(n)[1:]) in s]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's redo the alogirthm."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[]\n",
"[]\n"
]
}
],
"source": [
"digits = 1\n",
"solutions = get_primes_with_n_digits(digits)\n",
"results_left = []\n",
"\n",
"while solutions:\n",
" break\n",
" digits += 1\n",
" solutions = get_truncatable_numbers_left(get_primes_with_n_digits(digits), solutions)\n",
" for s in solutions:\n",
" results.append(s)\n",
" \n",
"print(results_left)\n",
"\n",
"digits = 1\n",
"solutions = get_primes_with_n_digits(digits)\n",
"results_right = []\n",
"\n",
"while solutions:\n",
" break\n",
" digits += 1\n",
" solutions = get_truncatable_numbers_right(get_primes_with_n_digits(digits), solutions)\n",
" for s in solutions:\n",
" results.append(s)\n",
" \n",
"print(results_right)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I added the terminate symbols because this algorithm did not even terminate. This means there are fairly big primes in either direction. We change the approach from bottom up into the other direction. Let's get all primes till a certain value and just check for them. Aka brute force. For this purpose we write a function that takes a number and checks if it is truncatable in both directions."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"primes_till_10000 = set(sieve_of_eratosthenes(10000))\n",
"\n",
"def is_right_truncatable(number, targets):\n",
" try:\n",
" while True:\n",
" number = int(str(number)[:-1])\n",
" if not number in targets:\n",
" return False\n",
" except ValueError:\n",
" return True\n",
"\n",
"assert(is_right_truncatable(3797, primes_till_10000))\n",
"assert(is_right_truncatable(3787, primes_till_10000) == False)\n",
"\n",
"def is_left_truncatable(number, targets):\n",
" try:\n",
" while True:\n",
" number = int(str(number)[1:])\n",
" if not number in targets:\n",
" return False\n",
" except ValueError:\n",
" return True\n",
"\n",
"assert(is_left_truncatable(3797, primes_till_10000))\n",
"assert(is_left_truncatable(3787, primes_till_10000) == False)\n",
"\n",
"def is_truncatable(number, targets):\n",
" if is_left_truncatable(number, targets) and is_right_truncatable(number, targets):\n",
" return True\n",
" return False\n",
"\n",
"assert(is_truncatable(3797, primes_till_10000))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's just go for a brute force till 10k and see what we get."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[2, 3, 5, 7, 23, 37, 53, 73, 313, 317, 373, 797, 3137, 3797]\n"
]
}
],
"source": [
"s = [p for p in primes_till_10000 if is_truncatable(p, primes_till_10000)]\n",
"print(s)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The one digit numbers are not relevant but this means we got only ten solutions. So we actually have to try all numbers till $10^{6}$. As it turned out we actually have to add one more digit. This is really ugly brute force. I do not like it. But seems like we got a solution."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[2, 3, 5, 7, 23, 37, 53, 73, 313, 317, 373, 797, 3137, 3797, 739397]\n",
"748317\n"
]
}
],
"source": [
"primes_till_100000 = set(sieve_of_eratosthenes(1000000))\n",
"s = [p for p in primes_till_100000 if is_truncatable(p, primes_till_100000)]\n",
"print(s)\n",
"print(sum(s[4:]))\n",
"s = sum(s[4:])\n",
"assert(s == 748317)"
]
}
],
"metadata": {
"completion_date": "Sun, 13 May 2018, 16:46",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
@ -25,7 +320,11 @@
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.5"
}
},
"tags": [
"primes",
"truncated"
]
},
"nbformat": 4,
"nbformat_minor": 0

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,61 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Euler Problem 38\n",
"\n",
"Take the number 192 and multiply it by each of 1, 2, and 3:\n",
"\n",
"$192 \\times 1 = 192$\n",
"\n",
"$192 \\times 2 = 384$\n",
"\n",
"$192 \\times 3 = 576$\n",
"\n",
"By concatenating each product we get the 1 to 9 pandigital, 192384576. We will call 192384576 the concatenated product of 192 and (1,2,3)\n",
"\n",
"The same can be achieved by starting with 9 and multiplying by 1, 2, 3, 4, and 5, giving the pandigital, 918273645, which is the concatenated product of 9 and (1,2,3,4,5).\n",
"\n",
"What is the largest 1 to 9 pandigital 9-digit number that can be formed as the concatenated product of an integer with (1,2, ... , n) where n > 1?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"completion_date": "",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.5"
},
"tags": [
"concatenated",
"product",
"pandigital"
]
},
"nbformat": 4,
"nbformat_minor": 0
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,53 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Euler Problem 39\n",
"\n",
"If p is the perimeter of a right angle triangle with integral length sides, {a,b,c}, there are exactly three solutions for p = 120.\n",
"\n",
"$\\{20,48,52\\}, \\{24,45,51\\}, \\{30,40,50\\}$\n",
"\n",
"For which value of p ≤ 1000, is the number of solutions maximised?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"completion_date": "",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.5"
},
"tags": [
"triangle",
"right",
"integer"
]
},
"nbformat": 4,
"nbformat_minor": 0
}

View File

@ -533,6 +533,62 @@
</td>
</tr>
<tr>
<td>Problem 036</td>
<td>Fri, 11 May 2018, 02:38</td>
<td><a href="EulerProblem036.html">Problem 036</a></td>
<td>
<kbd>palindrome</kbd>
<kbd>brute force</kbd>
</td>
</tr>
<tr>
<td>Problem 037</td>
<td>Sun, 13 May 2018, 16:46</td>
<td><a href="EulerProblem037.html">Problem 037</a></td>
<td>
<kbd>primes</kbd>
<kbd>truncated</kbd>
</td>
</tr>
<tr>
<td>Problem 038</td>
<td></td>
<td><a href="EulerProblem038.html">Problem 038</a></td>
<td>
<kbd>concatenated</kbd>
<kbd>product</kbd>
<kbd>pandigital</kbd>
</td>
</tr>
<tr>
<td>Problem 039</td>
<td></td>
<td><a href="EulerProblem039.html">Problem 039</a></td>
<td>
<kbd>triangle</kbd>
<kbd>right</kbd>
<kbd>integer</kbd>
</td>
</tr>
<tr>
<td>Problem 067</td>
<td>Fri, 5 Sep 2014, 07:36</td>