Add files via upload

This commit is contained in:
Peter Norvig
2017-08-24 23:49:03 -07:00
committed by GitHub
parent d7c6c35666
commit 1cce1fe2ee

View File

@@ -503,8 +503,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 28.2 s, sys: 653 ms, total: 28.9 s\n",
"Wall time: 28.9 s\n"
"CPU times: user 29.1 s, sys: 713 ms, total: 29.8 s\n",
"Wall time: 29.8 s\n"
]
},
{
@@ -784,8 +784,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 1min 2s, sys: 973 ms, total: 1min 3s\n",
"Wall time: 1min 3s\n"
"CPU times: user 1min 4s, sys: 1.12 s, total: 1min 5s\n",
"Wall time: 1min 5s\n"
]
},
{
@@ -979,7 +979,7 @@
"source": [
"I suspect that all of these actually should be exactly 2016. \n",
"\n",
"To find out for sure, let's re-do all the calculations using exact rational arithmetic, as provided by the `fractions.Fraction` data type. From experience I know that this will be an order of magnitude slower, so we're looking at maybe a 20 minute computation.\n",
"To find out for sure, let's re-do all the calculations using exact rational arithmetic, as provided by the `fractions.Fraction` data type. From experience I know that this will be an order of magnitude slower, so we're looking at 10 minutes or more of computation.\n",
"\n",
"I'll replace the computation `L / R` with `divide(L, R)`, which calls `Fraction`. To mitigate the expense of this computation, I make two optimizations. First, `divide` replaces a whole fraction, such as `Fraction(6, 2)`, with an `int`, such as `3`. Second, I modify `expr` to *not* fill in `EXPS[c10]`, except for `EXPS[c10][2016]`. The rationale is that we don't need the other entries, and by not storing them, we save a lot of memory, and thus save garbage collection time."
]
@@ -1058,8 +1058,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 13min 21s, sys: 6.11 s, total: 13min 28s\n",
"Wall time: 13min 33s\n"
"CPU times: user 12min 25s, sys: 1.44 s, total: 12min 26s\n",
"Wall time: 12min 27s\n"
]
},
{
@@ -1094,138 +1094,6 @@
"That did indeed take about ten times longer, but we now have an answer that I have more confidence in (but I wouldn't accept it as definitive until it was independently verified and had an extensive test suite). And of course, if you have a different definition of \"distinct solution,\" you will get a different answer."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"There are some additional interesting questions we can answer:\n",
"\n",
"What's the smallest positive integer than *cannot* be made?"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"button": false,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def unmakeable(numbers):\n",
" \"Smallest positive integer than can't be made by numbers.\"\n",
" return next(i for i in itertools.count(1) if i not in expressions(numbers))\n",
"\n",
"unmakeable(c10)"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"What is the expected theoretical number of expressions? \n",
"\n",
"It is [Catalan(9)](http://www.wolframalpha.com/input/?i=9th+catalan+number) &times; 4<sup>9</sup>:"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"button": false,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"1274544128"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"4862 * 4 ** 9"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"How many expressions were actually entered in the `COUNTS` table?"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"button": false,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"44499"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sum(COUNTS[c10].values())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So, about 1% of the 1.27 billion theoretically possible expressions do not appear in `COUNTS`; these are the `ZeroDivisionErrors`."
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -1244,7 +1112,7 @@
"- **Irrationals**: `(3 ** (1 / 2))` is an irrational number; so we can't do exact rational arithmetic.\n",
"- **Imaginaries**: `(-1 ** (1 / 2))` is an imaginary number, but Python gives a `ValueError`.\n",
"- **Overflow**: `(10. ** (9. ** 8.))`, as a `float`, gives a `OverflowError`.\n",
"- **Finite memory**: [`(10 ** (9 ** (8 * 7)))`](http://www.wolframalpha.com/input/?i=10+%5E+9+%5E+56), as an `int`, gives an `OutOfMemoryError` (even if your memory was expanded to use every atom in the universe).\n",
"- **Finite memory**: [`(10 ** (9 ** (8 * 7)))`](http://www.wolframalpha.com/input/?i=10+%5E+9+%5E+56), as an `int`, gives an `OutOfMemoryError` (even if your memory was expanded to use every atom on Earth).\n",
"\n",
"How do we deal with this? We can't do exact rational arithmetic. We could try to do exact *algebra*, perhaps using [SymPy](http://www.sympy.org/en/index.html), but that seems difficult\n",
"and computationally expensive, so instead I will abandon the goal of exact computation, and do everything in the domain of floats (reluctantly accepting that there will be some round-off errors). We'll coerce numbers to floats when we first put them in the table, and all subsequent operations will be with floats. I define a new function, `expr2`, to call `expr`, catching arithmetic errors. Since we are making some rather arbitrary decisions about what expressions are allowed (e.g. imaginary numbers are not), I'll give up on trying to maintain `COUNTS`."
@@ -1252,7 +1120,7 @@
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": 23,
"metadata": {
"button": false,
"new_sheet": false,
@@ -1306,7 +1174,7 @@
},
{
"cell_type": "code",
"execution_count": 27,
"execution_count": 24,
"metadata": {
"button": false,
"new_sheet": false,
@@ -1321,7 +1189,7 @@
"'(((4**4)-4)*(4+4))'"
]
},
"execution_count": 27,
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
@@ -1347,7 +1215,7 @@
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": 25,
"metadata": {
"button": false,
"new_sheet": false,
@@ -1359,9 +1227,12 @@
"source": [
"def makeable(numbers):\n",
" \"A table of {i: expression} for all integers i from 0 up to first unmakeable.\"\n",
" targets = range(unmakeable(numbers))\n",
" return {i: expressions(numbers)[i]\n",
" for i in targets}"
" for i in range(unmakeable(numbers))}\n",
"\n",
"def unmakeable(numbers):\n",
" \"Smallest positive integer than can't be made by numbers.\"\n",
" return next(i for i in itertools.count(1) if i not in expressions(numbers))"
]
},
{
@@ -1379,7 +1250,7 @@
},
{
"cell_type": "code",
"execution_count": 29,
"execution_count": 26,
"metadata": {
"button": false,
"new_sheet": false,
@@ -1403,7 +1274,7 @@
" 9: '(((4/4)+4)+4)'}"
]
},
"execution_count": 29,
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
@@ -1429,7 +1300,7 @@
},
{
"cell_type": "code",
"execution_count": 30,
"execution_count": 27,
"metadata": {
"button": false,
"new_sheet": false,
@@ -1456,7 +1327,7 @@
" 12: '((((5+5)/5)+5)+5)'}"
]
},
"execution_count": 30,
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
@@ -1485,7 +1356,7 @@
"\n",
"- **digit concatenation**: `55`\n",
"- **decimal point**: `.5`\n",
"- **unary operations**: `5!`, &radic; `5`\n",
"- **unary operations**: `5!` and &radic; `5`\n",
"\n",
"\n",
"We'll refactor `expressions` to call these three new subfunctions:\n",
@@ -1499,7 +1370,7 @@
},
{
"cell_type": "code",
"execution_count": 31,
"execution_count": 28,
"metadata": {
"button": false,
"new_sheet": false,
@@ -1563,7 +1434,7 @@
},
{
"cell_type": "code",
"execution_count": 32,
"execution_count": 29,
"metadata": {
"button": false,
"collapsed": true,
@@ -1596,7 +1467,7 @@
},
{
"cell_type": "code",
"execution_count": 33,
"execution_count": 30,
"metadata": {
"button": false,
"new_sheet": false,
@@ -1609,8 +1480,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 48.3 s, sys: 2 s, total: 50.3 s\n",
"Wall time: 50.7 s\n"
"CPU times: user 43.5 s, sys: 1.44 s, total: 45 s\n",
"Wall time: 45 s\n"
]
},
{
@@ -1775,7 +1646,7 @@
" 156: '((5!+(5!*5.5))/5)'}"
]
},
"execution_count": 33,
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
@@ -1832,7 +1703,7 @@
},
{
"cell_type": "code",
"execution_count": 34,
"execution_count": 31,
"metadata": {
"button": false,
"collapsed": true,
@@ -1881,7 +1752,7 @@
},
{
"cell_type": "code",
"execution_count": 35,
"execution_count": 32,
"metadata": {
"button": false,
"new_sheet": false,
@@ -1894,8 +1765,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 2min 42s, sys: 2.81 s, total: 2min 45s\n",
"Wall time: 2min 46s\n"
"CPU times: user 2min 25s, sys: 1.42 s, total: 2min 26s\n",
"Wall time: 2min 26s\n"
]
},
{
@@ -2904,7 +2775,7 @@
" ...}"
]
},
"execution_count": 35,
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
@@ -2930,7 +2801,7 @@
},
{
"cell_type": "code",
"execution_count": 36,
"execution_count": 33,
"metadata": {
"button": false,
"new_sheet": false,
@@ -2945,7 +2816,7 @@
"23308"
]
},
"execution_count": 36,
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}