euler/ipython/EulerProblem027.ipynb

143 lines
4.4 KiB
Plaintext
Raw Normal View History

2018-02-08 18:09:51 +01:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Euler Problem 27\n",
"\n",
"Euler discovered the remarkable quadratic formula:\n",
"\n",
"$n^2 + n + 41$\n",
"\n",
"It turns out that the formula will produce 40 primes for the consecutive integer values 0≤n≤39. However, when $n=40$, $40^2 + 40 + 41 = 40(40+1)+41$ is divisible by $41$, and certainly when $n=41,41^2+41+41$ is clearly divisible by 41.\n",
"\n",
"The incredible formula $n^279n+1601$ was discovered, which produces 80 primes for the consecutive values 0≤n≤79. The product of the coefficients, $79$ and $1601$, is $126479$.\n",
"\n",
"Considering quadratics of the form:\n",
"\n",
"$n^2 + an +b$, where |a|<1000 and |b|≤1000\n",
"\n",
"where |n| is the modulus/absolute value of n e.g. |11|=11 and |4|=4.\n",
"\n",
"Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n=0."
]
},
{
"cell_type": "markdown",
2018-02-08 18:09:51 +01:00
"metadata": {
"collapsed": true
},
"source": [
"Okay, bruteforcing this complete thing is definitely hard. The interesting thing is that euler provided two examples. If we calculate the primes for both terms we see that there is a certain overlap. This indicates that there is a relation between the two. Sure enough if we put $n-40$ into the first term we get the following.\n",
"\n",
"$(n - 40)^2 + (n - 40) + 41 = n^2 - 80n + 1600 + n - 40 + 41 = n^2 - 79n +1601$\n",
"\n",
"Let's assume that all incredible formulas can be derived by inserting $(n - p)$ into the formula. Of course, what ever value we choose for p the resulting terms must not exceed the boundaries for a or b. We calculate the boundaries.\n",
"\n",
"$(n-p)^2 + (n-p) + 41 = n^2 + n(-2p + 1) + p^2 - p + 41$\n",
"\n",
"Where $(-2p + 1) = a$ and $p^2 -p + 41 = b$. We can now calulate the bounds for a:\n",
"\n",
"$-2p + 1 > -1000 \\rightarrow p < 500.5$\n",
"\n",
"$-2 p + 1 < 1000 \\rightarrow p > -499.5$\n",
"\n",
"And b:\n",
"\n",
"$p^2 - p + 41 <= 1000$\n",
"\n",
"$-30.472 < p < 31.472$\n",
"\n",
"$p^2 - p + 41 >= 1000$ True for $\\forall p \\in \\mathbb{N}$\n",
"\n",
"So now we only have to check for the values p in range(-30, 32). Alternatively, for the example $p = 40$ was used, maybe the next smaller value $p = 31$ yields the correct solution:\n",
"\n",
"$s = a\\times b = (-2 * 31 + 1) * (31^2 - 31 + 41) = -61 \\times 971 = -59231$"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"-59231"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from functools import lru_cache\n",
"\n",
"@lru_cache(maxsize=1000)\n",
"def is_prime(n):\n",
" if n < 2:\n",
" return False\n",
" from math import sqrt\n",
" for s in range(2, int(sqrt(n) + 1)):\n",
" if n % s == 0:\n",
" return False\n",
" if s * s > n:\n",
" return True\n",
" return True\n",
" \n",
"assert(is_prime(41) == True)\n",
"\n",
"def get_quadratic(n, p):\n",
" return n*n + n * (-2* p + 1) + p*p - p + 41\n",
"\n",
"n_max = 0\n",
"p_max = 0\n",
"\n",
"for p in range(-30, 32):\n",
" for n in range(0, 10000):\n",
" if not is_prime(get_quadratic(n, p)) and n > n_max:\n",
" n_max = n\n",
" p_max = p\n",
" break\n",
"\n",
"p = p_max\n",
"s = (-2 * p + 1) * (p*p - p + 41)\n",
"assert(s == -59231)\n",
"s"
]
2018-02-08 18:09:51 +01:00
}
],
"metadata": {
"completion_date": "Mon, 21 Aug 2017, 21:11",
"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.4"
},
"tags": [
"quadratic",
"primes",
"formula",
"brain"
2018-02-08 18:09:51 +01:00
]
},
"nbformat": 4,
"nbformat_minor": 0
}