Add files via upload

This commit is contained in:
Peter Norvig 2018-04-06 17:50:12 -07:00 committed by GitHub
parent 51cdd63b5b
commit 8f7f1a718d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -33,7 +33,7 @@
"\n",
"# Online Beal Counterexample Checker\n",
"\n",
"Got a counterexample? Check it with my [Online Beal Counterexample Checker](http://norvig.com/bealcheck.html).\n",
"Got a counterexample? Verify it with my [Beal Counterexample Checker](http://norvig.com/bealcheck.html).\n",
"\n",
"# How to Not Win A Million Dollars\n",
"\n",
@ -88,46 +88,13 @@
"output_type": "execute_result"
}
],
"source": [
"A, B, C = 60000000000000000000, 70000000000000000000, 82376613842809255677\n",
"x = y = z = 3.\n",
"A ** x + B ** y == C ** z"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"That's interesting; the equality is true. But to show that this is a valid counterexample, we have to show that `A, B, C` have no common factor; that is, that their greatest common divisor (`gcd`) is 1:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"button": false,
"collapsed": false,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from math import gcd #### In Python versions < 3.5, use \"from fractions import gcd\"\n",
"\n",
"gcd(gcd(A, B), C) == 1"
"A, B, C = 60000000000000000000, 70000000000000000000, 82376613842809255677\n",
"x = y = z = 3.\n",
"\n",
"A ** x + B ** y == C ** z and gcd(gcd(A, B), C) == 1"
]
},
{
@ -140,14 +107,14 @@
}
},
"source": [
"**WOW! The result is `True`!** Is this a real counterexample to Beal? And also a disproof of Fermat's Last Theorem?\n",
"**WOW! The result is `True`!** The two sides of the equation are equal, and the greatest common divisor is 1. Is this a real counterexample to Beal? And also a disproof of Fermat's Last Theorem?\n",
"\n",
"Alas, it is not. The decimal point in \"`x = y = z = 3.`\" indicates a floating point number, with inexact, limited precision. Change the inexact \"`3.`\" to an exact \"`3`\" and the two sides of the equation are no longer equal. Below we see they are the same for the first 18 digits, but differ starting with the 19th: "
]
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 2,
"metadata": {
"button": false,
"collapsed": false,
@ -164,7 +131,7 @@
" 559000000000000000063037470301555182935702892172500189973733)"
]
},
"execution_count": 3,
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
@ -196,131 +163,92 @@
"$3987^{12} + 4365^{12} = 4472^{12}$ and $1782^{12} + 1841^{12} = 1922^{12}$. These were designed by *Simpsons* writer David X. Cohen to be correct up to the precision found in most handheld calculators. Cohen found the equations with a program that must have been something like this:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1782**12 + 1841**12 == 1922**12 has relative error of 3e-10\n",
"3987**12 + 4365**12 == 4472**12 has relative error of 2e-11\n"
]
}
],
"source": [
"from itertools import combinations\n",
"\n",
"def Fermat(A, B, n):\n",
" \"Return a tuple of the form (error, A, B, C, n)\"\n",
" C = int(round((A ** n + B ** n) ** (1/n)))\n",
" lhs, rhs = A ** n + B ** n, C ** n\n",
" error = abs(lhs - rhs) / rhs\n",
" return (error, A, B, C, n)\n",
"\n",
"def simpsons(bases, powers):\n",
" \"\"\"Find the Fermat equation that minimizes the error.\"\"\"\n",
" return min(Fermat(A, B, n) \n",
" for A, B in combinations(bases, 2) \n",
" for n in powers)\n",
"\n",
"def show(fermat):\n",
" (error, A, B, C, n) = fermat\n",
" print('{}**{} + {}**{} == {}**{} has relative error of {:.0g}'\n",
" .format(A, n, B, n, C, n, error))\n",
" \n",
"show(simpsons(range(1000, 2000), [12]))\n",
"show(simpsons(range(3000, 5000), [12]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These are the same two equations that David X. Cohen found. The sides of the equations are nearly equal, up to 10 or 11 decimal places, respectively.\n",
"\n",
"Can we do better? The following search will take about 8 minutes:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from collections import namedtuple\n",
"from itertools import combinations\n",
"\n",
"Fermat = namedtuple('Fermat', 'A, B, C, n')\n",
"\n",
"def err(equation):\n",
" \"The relative error in a Fermat-style equation\"\n",
" (A, B, C, n) = equation\n",
" return abs(A ** n + B ** n - C ** n) / C ** n\n",
"\n",
"def simpsons(bases, powers):\n",
" \"\"\"Find the Fermat equation that minimizes the error (the\n",
" difference between A ** n + B ** n and C ** n). \n",
" Let A, B range over all pairs of bases and n over all powers.\"\"\"\n",
" return min((Fermat(A, B, int((A ** n + B ** n) ** (1/n)), n) \n",
" for A, B in combinations(bases, 2) for n in powers),\n",
" key=err)"
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2196**3 + 5984**3 == 6081**3 has relative error of 4e-12\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"button": false,
"collapsed": false,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"Fermat(A=3987, B=4365, C=4472, n=12)"
"(224866629440, 224866629441)"
]
},
"execution_count": 5,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simpsons(range(3000, 5000), range(11, 14))"
"(_, A, B, C, n) = f = simpsons(range(1000, 6000), range(3, 13))\n",
"show(f)\n",
"A ** n + B ** n, C ** n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"button": false,
"collapsed": false,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"Fermat(A=1010, B=1897, C=1988, n=3)"
]
},
"execution_count": 6,
"cell_type": "markdown",
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simpsons(range(1000, 2000), range(3, 16))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"(63976656349698612616236230953154487896987106,\n",
" 63976656348486725806862358322168575784124416)"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3987 ** 12 + 4365 ** 12, 4472 ** 12"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"(2541210258614589176288669958142428526657,\n",
" 2541210259314801410819278649643651567616)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1782 ** 12 + 1841 ** 12, 1922 ** 12"
"This is an equation that differs by just 1 in the 12th and last decmal place."
]
},
{
@ -348,7 +276,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 5,
"metadata": {
"button": false,
"collapsed": true,
@ -414,7 +342,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 6,
"metadata": {
"button": false,
"collapsed": false,
@ -428,8 +356,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 362 ms, sys: 3.33 ms, total: 366 ms\n",
"Wall time: 406 ms\n"
"CPU times: user 354 ms, sys: 4.32 ms, total: 358 ms\n",
"Wall time: 376 ms\n"
]
}
],
@ -447,12 +375,12 @@
}
},
"source": [
"The execution time goes up roughly with the square of `max_A`, so the following should take about 100 times longer:"
"The execution time goes up roughly with the square of `max_A`, so the following should take about 25 times longer:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 7,
"metadata": {
"button": false,
"collapsed": false,
@ -466,13 +394,13 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 43.3 s, sys: 335 ms, total: 43.7 s\n",
"Wall time: 46.5 s\n"
"CPU times: user 11.1 s, sys: 152 ms, total: 11.3 s\n",
"Wall time: 12.3 s\n"
]
}
],
"source": [
"%time beal(1000, 100)"
"%time beal(500, 100)"
]
},
{
@ -497,7 +425,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 8,
"metadata": {
"button": false,
"collapsed": false,
@ -518,7 +446,7 @@
" 6: [216, 1296, 7776, 279936]}"
]
},
"execution_count": 12,
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
@ -543,7 +471,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 9,
"metadata": {
"button": false,
"collapsed": false,
@ -579,7 +507,7 @@
" 279936: 6}"
]
},
"execution_count": 13,
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
@ -591,7 +519,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 10,
"metadata": {
"collapsed": false
},
@ -602,7 +530,7 @@
"3"
]
},
"execution_count": 14,
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
@ -631,7 +559,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 11,
"metadata": {
"button": false,
"collapsed": false,
@ -680,7 +608,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 12,
"metadata": {
"button": false,
"collapsed": false,
@ -696,7 +624,7 @@
"{True}"
]
},
"execution_count": 16,
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
@ -730,7 +658,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 13,
"metadata": {
"button": false,
"collapsed": true,
@ -761,7 +689,7 @@
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 14,
"metadata": {
"button": false,
"collapsed": false,
@ -777,7 +705,7 @@
"'tests pass'"
]
},
"execution_count": 18,
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
@ -882,7 +810,7 @@
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 15,
"metadata": {
"button": false,
"collapsed": true,
@ -947,7 +875,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 16,
"metadata": {
"collapsed": false
},
@ -963,7 +891,7 @@
" 6: [(216, 3), (296, 4), (776, 5), (936, 7)]}"
]
},
"execution_count": 20,
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
@ -989,7 +917,7 @@
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": 17,
"metadata": {
"button": false,
"collapsed": false,
@ -1024,7 +952,7 @@
" 936: [(6, 7)]})"
]
},
"execution_count": 21,
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
@ -1048,7 +976,7 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 18,
"metadata": {
"button": false,
"collapsed": false,
@ -1062,8 +990,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 1min 2s, sys: 646 ms, total: 1min 3s\n",
"Wall time: 1min 8s\n"
"CPU times: user 55.9 s, sys: 530 ms, total: 56.4 s\n",
"Wall time: 59.6 s\n"
]
}
],