Compare commits
11 Commits
5a24488608
...
414fe258a4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
414fe258a4 | ||
|
|
f6bf8d2582 | ||
|
|
23d26c769d | ||
|
|
506ef02f1a | ||
|
|
ee268061e8 | ||
|
|
901d91cecc | ||
|
|
a322653542 | ||
|
|
f2c0867cd6 | ||
|
|
f3ee63aac1 | ||
|
|
a9ea174313 | ||
|
|
f0007cabe0 |
14
README.md
14
README.md
@@ -26,8 +26,11 @@ For each notebook you can hover on the title to see a description, or click the
|
|||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/lispy.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/lispy.ipynb) | 2026 | <a href="ipynb/lispy.ipynb" title="Tutorial on interpreters.">(How to Write a (Lisp) Interpreter (in Python))</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/lispy.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/lispy.ipynb) | 2026 | <a href="ipynb/lispy.ipynb" title="Tutorial on interpreters.">(How to Write a (Lisp) Interpreter (in Python))</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/RationalPi.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/RationalPi.ipynb) | 2026 | <a href="ipynb/RationalPi.ipynb" title="Using continued fractions to find fractions (like 22/7) that are close to pi.">Approximating Pi with a Fraction</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/RationalPi.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/RationalPi.ipynb) | 2026 | <a href="ipynb/RationalPi.ipynb" title="Using continued fractions to find fractions (like 22/7) that are close to pi.">Approximating Pi with a Fraction</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/clvr.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/clvr.ipynb) | 2026 | <a href="ipynb/clvr.ipynb" title="Guess famous phrases from letter shapes. Beginner level.">Did you solve it? R y clvr ngh t rd ths sntnc?</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/clvr.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/clvr.ipynb) | 2026 | <a href="ipynb/clvr.ipynb" title="Guess famous phrases from letter shapes. Beginner level.">Did you solve it? R y clvr ngh t rd ths sntnc?</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler3.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler3.ipynb) | 2026 | <a href="ipynb/Euler3.ipynb" title="For beginner programmers: How to find the largest prime factor of a number">Project Euler #3: Largest prime factor</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler3.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler3.ipynb) | 2026 | <a href="ipynb/Euler3.ipynb" title="For beginner programmers: How to find the largest prime factor of a number. Project Euler #3.">Largest prime factor</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler.ipynb) | 2026 | <a href="ipynb/Euler.ipynb" title="Solutions to the first 100 Project Euler math/programming problems">Project Euler 1–100</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler-Fable.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler-Fable.ipynb) | 2026 | <a href="ipynb/Euler-Fable.ipynb" title="Solutions to Project Euler math/programming problems by Claude Fable LLM">Project Euler #1–100 by Fable LLM</a> |
|
||||||
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler-Kimi.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler-Kimi.ipynb) | 2026 | <a href="ipynb/Euler-Kimi.ipynb" title="Solutions to Project Euler math/programming problems by Kimi LLM">Project Euler #1–100 by Kimi LLM</a> |
|
||||||
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler-Opus.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler-Opus.ipynb) | 2026 | <a href="ipynb/Euler-Opus.ipynb" title="Solutions to Project Euler math/programming problems by Claude Opus LLM">Project Euler #1–100 by Opus LLM</a> |
|
||||||
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler.ipynb) | 2026 | <a href="ipynb/Euler.ipynb" title="Solutions to the first 100 Project Euler math/programming problems">Project Euler #1–100 by a Human</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/TruncatablePrimes.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/TruncatablePrimes.ipynb) | 2026 | <a href="ipynb/TruncatablePrimes.ipynb" title="Prime numbers where you can remove digits and still get primes.">Truncatable Primes</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/TruncatablePrimes.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/TruncatablePrimes.ipynb) | 2026 | <a href="ipynb/TruncatablePrimes.ipynb" title="Prime numbers where you can remove digits and still get primes.">Truncatable Primes</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2025.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2025.ipynb) | 2025 | <a href="ipynb/Advent-2025.ipynb" title="Puzzle site with a coding puzzle for 12 days of Christmas, December 2025">Advent of Code 2025</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2025.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2025.ipynb) | 2025 | <a href="ipynb/Advent-2025.ipynb" title="Puzzle site with a coding puzzle for 12 days of Christmas, December 2025">Advent of Code 2025</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2025-AI.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2025-AI.ipynb) | 2025 | <a href="ipynb/Advent-2025-AI.ipynb" title="Using large language coding models to solve AoC puzzles">Advent of Code 2025: AI LLM Edition</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2025-AI.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2025-AI.ipynb) | 2025 | <a href="ipynb/Advent-2025-AI.ipynb" title="Using large language coding models to solve AoC puzzles">Advent of Code 2025: AI LLM Edition</a> |
|
||||||
@@ -65,8 +68,11 @@ For each notebook you can hover on the title to see a description, or click the
|
|||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2017.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2017.ipynb) | 2017 | <a href="ipynb/Advent-2017.ipynb" title="Puzzle site with a coding puzzle each day of Advent, December 2017">Advent of Code 2017</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2017.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2017.ipynb) | 2017 | <a href="ipynb/Advent-2017.ipynb" title="Puzzle site with a coding puzzle each day of Advent, December 2017">Advent of Code 2017</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2016.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2016.ipynb) | 2016 | <a href="ipynb/Advent-2016.ipynb" title="Puzzle site with a coding puzzle each day of Advent, December 2016">Advent of Code 2016</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2016.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2016.ipynb) | 2016 | <a href="ipynb/Advent-2016.ipynb" title="Puzzle site with a coding puzzle each day of Advent, December 2016">Advent of Code 2016</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb) | 2022 | <a href="ipynb/AdventUtils.ipynb" title="Utility functions for Advent of Code puzzles">Advent of Code Utilities</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb) | 2022 | <a href="ipynb/AdventUtils.ipynb" title="Utility functions for Advent of Code puzzles">Advent of Code Utilities</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler.ipynb) | 2026 | <a href="ipynb/Euler.ipynb" title="Solutions to the first 100 Project Euler math/programming problems">Project Euler 1–100</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler.ipynb) | 2026 | <a href="ipynb/Euler.ipynb" title="Solutions to the first 100 Project Euler math/programming problems">Project Euler #1–100 by a Human</a> |
|
||||||
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler3.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler3.ipynb) | 2026 | <a href="ipynb/Euler3.ipynb" title="For beginner programmers: How to find the largest prime factor of a number">Project Euler #3: Largest prime factor</a> |
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler-Fable.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler-Fable.ipynb) | 2026 | <a href="ipynb/Euler-Fable.ipynb" title="Solutions to Project Euler math/programming problems by Claude Fable LLM">Project Euler #1–100 by Fable LLM</a> |
|
||||||
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler-Opus.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler-Opus.ipynb) | 2026 | <a href="ipynb/Euler-Opus.ipynb" title="Solutions to Project Euler math/programming problems by Claude Opus LLM">Project Euler #1–100 by Opus LLM</a> |
|
||||||
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler-Kimi.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler-Kimi.ipynb) | 2026 | <a href="ipynb/Euler-Kimi.ipynb" title="Solutions to Project Euler math/programming problems by Kimi LLM">Project Euler #1–100 by Kimi LLM</a> |
|
||||||
|
| [co](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Euler3.ipynb) [nb](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Euler3.ipynb) | 2026 | <a href="ipynb/Euler3.ipynb" title="For beginner programmers: How to find the largest prime factor of a number. Project Euler #3.">Largest prime factor</a> |
|
||||||
|
|
||||||
|
|
||||||
|Open|Year|Probability and Uncertainty|
|
|Open|Year|Probability and Uncertainty|
|
||||||
|
|||||||
4739
ipynb/Euler-Fable.ipynb
Normal file
4739
ipynb/Euler-Fable.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
4801
ipynb/Euler-Kimi.ipynb
Normal file
4801
ipynb/Euler-Kimi.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
5191
ipynb/Euler-Opus.ipynb
Normal file
5191
ipynb/Euler-Opus.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@
|
|||||||
" The prime factors of 13195 are 5, 7, 13 and 29.\n",
|
" The prime factors of 13195 are 5, 7, 13 and 29.\n",
|
||||||
" What is the largest prime factor of the number 600851475143?\n",
|
" What is the largest prime factor of the number 600851475143?\n",
|
||||||
"\n",
|
"\n",
|
||||||
"I'll describe here how I think about this problem, at alevel suitable for a novice programmer. There are two things to get right: the general plan of how to attack this problem, and the details of how to say it in Python.\n",
|
"I'll describe here how I think about this problem, at a level suitable for a novice programmer. There are two things to get right: the general plan of how to attack this problem, and the details of how to say it in Python.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"## The General Plan\n",
|
"## The General Plan\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
"id": "8bf8dd51-8e06-4572-85fa-fe42875e0305",
|
"id": "8bf8dd51-8e06-4572-85fa-fe42875e0305",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"We can represent the execution of the program as a series of equations, one per line. Using `F` as an abbreviation for `largest_prime_factor`, here is hjow we find the largest prime factor of 360:\n",
|
"We can represent the execution of the program as a series of equations, one per line. Using `F` as an abbreviation for `largest_prime_factor`, here is how we find the largest prime factor of 360:\n",
|
||||||
"\n",
|
"\n",
|
||||||
" F(360) = max(2, F(180))\n",
|
" F(360) = max(2, F(180))\n",
|
||||||
" F(180) = max(2, F(90))\n",
|
" F(180) = max(2, F(90))\n",
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
" F(45) = max(3, F(15))\n",
|
" F(45) = max(3, F(15))\n",
|
||||||
" F(15) = max(3, F(5))\n",
|
" F(15) = max(3, F(5))\n",
|
||||||
" F(5) = 5\n",
|
" F(5) = 5\n",
|
||||||
" F(36) = max(2, max(2, max(2, 3, 3, 5))) = 5"
|
" F(36) = max(2, max(2, max(2, 3, max(3, 5)))) = 5"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"[11, 'out of', 11, 'tests pass']"
|
"[12, 'out of', 12, 'tests pass']"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 4,
|
"execution_count": 4,
|
||||||
@@ -173,11 +173,12 @@
|
|||||||
" 6: 3, # composite\n",
|
" 6: 3, # composite\n",
|
||||||
" 32: 2, # power of 2\n",
|
" 32: 2, # power of 2\n",
|
||||||
" 49: 7, # square of a prime\n",
|
" 49: 7, # square of a prime\n",
|
||||||
" 97: 97, # bigger prime\n",
|
|
||||||
" 99991: 99991, # even bigger prime\n",
|
|
||||||
" 97**9: 97, # even bigger power of a prime\n",
|
|
||||||
" 360: 5, # test case for equations above\n",
|
" 360: 5, # test case for equations above\n",
|
||||||
" 600851475143: 6857 # Project Euler #3\n",
|
" 997: 997, # bigger prime\n",
|
||||||
|
" 997**9: 997, # bigger power of a prime\n",
|
||||||
|
" 99991: 99991, # even bigger prime\n",
|
||||||
|
" 600851475143: 6857, # Project Euler #3\n",
|
||||||
|
" 99999989: 99999989 # An 8-digit prime number\n",
|
||||||
" }\n",
|
" }\n",
|
||||||
" correct = sum(largest_prime_factor(n) == cases[n] for n in cases)\n",
|
" correct = sum(largest_prime_factor(n) == cases[n] for n in cases)\n",
|
||||||
" return [correct, 'out of', len(cases), 'tests pass']\n",
|
" return [correct, 'out of', len(cases), 'tests pass']\n",
|
||||||
@@ -192,7 +193,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"## Efficiency\n",
|
"## Efficiency\n",
|
||||||
"\n",
|
"\n",
|
||||||
"How long does it take to get our answer? We can use `%time` to see it is just a few hundred microseconds (μs):"
|
"How long does it take to run all the test cases?"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -205,14 +206,14 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"CPU times: user 181 μs, sys: 0 ns, total: 181 μs\n",
|
"CPU times: user 2.01 s, sys: 15 ms, total: 2.02 s\n",
|
||||||
"Wall time: 183 μs\n"
|
"Wall time: 2.03 s\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"6857"
|
"[12, 'out of', 12, 'tests pass']"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 5,
|
"execution_count": 5,
|
||||||
@@ -221,45 +222,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"%time largest_prime_factor(600851475143)"
|
"%time tests()"
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "c8ead8e9-199f-47c6-ad76-360b1ebdaa02",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"The algorithm is slowest when *n* is prime, because the `for` loop has to go all the way up to *n*. How long would it take for the largest 8-digit prime, 99,999,989?"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 6,
|
|
||||||
"id": "7323d528-96d7-4c05-a05d-125e99605443",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"CPU times: user 1.9 s, sys: 18.4 ms, total: 1.92 s\n",
|
|
||||||
"Wall time: 1.92 s\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"99999989"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 6,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"n8 = 99999989 # An 8-digit number that happens to be prime \n",
|
|
||||||
"%time largest_prime_factor(n8)"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -269,14 +232,14 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"About 2 seconds. Maybe that's good enough. But could we speed things up?\n",
|
"About 2 seconds. Maybe that's good enough. But could we speed things up?\n",
|
||||||
"\n",
|
"\n",
|
||||||
"In trying to find a *p* that evenly divides *n*, the algorithm tests all the integers from 2 to *n*. But do we really have to test all those potential factors? No! Either *n* is prime, or it has two factors *p* and *q* such that *p* × *q* = *n*. Of those two factors, one must be less than or equal to the square root of *n*. So to determine if *n* has a prime factor other than itself, we only have to check integers up to √*n*, not all the way up to *n*. That's a big difference! for an 8-digit prime it is the difference between roughly 100 million steps versus a mere 10 thousand steps.\n",
|
"In trying to find a *p* that evenly divides *n*, the algorithm tests all the integers from 2 to *n*. But do we really have to test all those potential factors? No! Either *n* is prime, or it has two factors *p* and *q* such that *p* × *q* = *n*. Of those two factors, one must be less than or equal to the square root of *n*. So to determine if *n* has a prime factor other than itself, we only have to check integers up to √*n*, not all the way up to *n*. That's a big difference! For an 8-digit prime it is the difference between roughly 100 million steps versus a mere 10 thousand steps.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Let's change the definition of `largest_prime_factor` to incorporate this new trick. (We will `import` the square root function, `sqrt`, from the `math` module.)"
|
"Let's change the definition of `largest_prime_factor` to incorporate this new trick. (We will `import` the square root function, `sqrt`, from the `math` module.)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": 6,
|
||||||
"id": "b90b5407-4666-4925-99d2-6a3a6b192fac",
|
"id": "b90b5407-4666-4925-99d2-6a3a6b192fac",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
@@ -294,46 +257,17 @@
|
|||||||
" return n # n is prime or 1"
|
" return n # n is prime or 1"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"id": "c39b08b9-06ed-49c0-a277-db248de909fd",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"Any time you change a function, you should re-run the tests to give you some confidence that you didn't introduce a bug:"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 8,
|
|
||||||
"id": "4026dc87-a0aa-4c75-b92a-96ec24cda1b7",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"[11, 'out of', 11, 'tests pass']"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 8,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"tests()"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "6cddf393-a0fd-4cc2-9eef-3341339106bd",
|
"id": "6cddf393-a0fd-4cc2-9eef-3341339106bd",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Now we can see how fast the new function is on the 8-digit prime:"
|
"Now we can see how fast the new function is, and verify that it still passes all the tests:"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 9,
|
"execution_count": 7,
|
||||||
"id": "d3d0c13e-5c01-4112-b372-60f7eb302d25",
|
"id": "d3d0c13e-5c01-4112-b372-60f7eb302d25",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -341,23 +275,23 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"CPU times: user 196 μs, sys: 0 ns, total: 196 μs\n",
|
"CPU times: user 523 μs, sys: 5 μs, total: 528 μs\n",
|
||||||
"Wall time: 196 μs\n"
|
"Wall time: 548 μs\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"99999989"
|
"[12, 'out of', 12, 'tests pass']"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 9,
|
"execution_count": 7,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"%time largest_prime_factor(n8)"
|
"%time tests()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -365,14 +299,14 @@
|
|||||||
"id": "82b008ea-f6b5-4bcd-8768-09c8dab089cb",
|
"id": "82b008ea-f6b5-4bcd-8768-09c8dab089cb",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"As predicted, this is about 10,000 times faster.\n",
|
"This is thousands of times faster.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"We should be able to handle a 16-digit prime in about 2 seconds:"
|
"We should be able to handle a 16-digit prime in about 2 seconds:"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 10,
|
"execution_count": 8,
|
||||||
"id": "9b6030ef-626a-4195-aedb-ef2edac65da4",
|
"id": "9b6030ef-626a-4195-aedb-ef2edac65da4",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -380,8 +314,8 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"CPU times: user 1.96 s, sys: 19.3 ms, total: 1.97 s\n",
|
"CPU times: user 2.12 s, sys: 13 ms, total: 2.13 s\n",
|
||||||
"Wall time: 1.97 s\n"
|
"Wall time: 2.14 s\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -390,7 +324,7 @@
|
|||||||
"9927935178558959"
|
"9927935178558959"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 10,
|
"execution_count": 8,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@@ -414,17 +348,25 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 11,
|
"execution_count": 9,
|
||||||
"id": "0308612c-6860-49b0-bcd6-856fa08133b1",
|
"id": "0308612c-6860-49b0-bcd6-856fa08133b1",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"CPU times: user 522 μs, sys: 1 μs, total: 523 μs\n",
|
||||||
|
"Wall time: 525 μs\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"[11, 'out of', 11, 'tests pass']"
|
"[12, 'out of', 12, 'tests pass']"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 11,
|
"execution_count": 9,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@@ -440,9 +382,10 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"def smallest_prime_factor(n):\n",
|
"def smallest_prime_factor(n):\n",
|
||||||
" \"\"\"The smallest prime that evenly divides n (or n itself if no prime divisors).\"\"\"\n",
|
" \"\"\"The smallest prime that evenly divides n (or n itself if no prime divisors).\"\"\"\n",
|
||||||
" return next((p for p in range(2, int(sqrt(n) + 1)) if n % p == 0), n)\n",
|
" divisors = (p for p in range(2, int(sqrt(n) + 1)) if n % p == 0)\n",
|
||||||
|
" return next(divisors, n)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"tests()"
|
"%time tests()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -455,17 +398,25 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 12,
|
"execution_count": 10,
|
||||||
"id": "b8907a8f-872f-4531-825c-fae9c70211c1",
|
"id": "b8907a8f-872f-4531-825c-fae9c70211c1",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"CPU times: user 490 μs, sys: 1 μs, total: 491 μs\n",
|
||||||
|
"Wall time: 492 μs\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"[11, 'out of', 11, 'tests pass']"
|
"[12, 'out of', 12, 'tests pass']"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 12,
|
"execution_count": 10,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@@ -485,15 +436,23 @@
|
|||||||
" p = p + 1\n",
|
" p = p + 1\n",
|
||||||
" return max(n, largest)\n",
|
" return max(n, largest)\n",
|
||||||
" \n",
|
" \n",
|
||||||
"tests()"
|
"%time tests()"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "4f44c6ec-7126-4bc8-9ce2-3fb23154791d",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"kernelspec": {
|
"kernelspec": {
|
||||||
"display_name": "Python 3 (ipykernel)",
|
"display_name": "Python [conda env:base] *",
|
||||||
"language": "python",
|
"language": "python",
|
||||||
"name": "python3"
|
"name": "conda-base-py"
|
||||||
},
|
},
|
||||||
"language_info": {
|
"language_info": {
|
||||||
"codemirror_mode": {
|
"codemirror_mode": {
|
||||||
|
|||||||
@@ -1,5 +1,68 @@
|
|||||||
|
#### Project Euler: data and problem running harness
|
||||||
|
#### Used by Euler.ipynb and Euler-LLM.upynb
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from statistics import mean, median
|
||||||
|
import time
|
||||||
|
|
||||||
|
#### Harness: `run(euler_1)` to record and data and `runs()` to display it
|
||||||
|
|
||||||
|
RUNS = {}
|
||||||
|
|
||||||
|
class run:
|
||||||
|
"""Verify that calling `euler_n()` computes the `EXPECTED` result.
|
||||||
|
Store run objects in `RUNS`."""
|
||||||
|
def __init__(self, euler_n):
|
||||||
|
n = int(euler_n.__name__.split('_')[1])
|
||||||
|
self.n = n
|
||||||
|
RUNS[n] = self
|
||||||
|
self.title = (euler_n.__doc__ or '?:').split(':')[0]
|
||||||
|
start = time.perf_counter()
|
||||||
|
self.got = euler_n()
|
||||||
|
self.msecs = round((time.perf_counter() - start) * 1000)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
expected = EXPECTED[self.n]
|
||||||
|
check = ('✅' if (self.got == expected) else f'❌ (expected {expected})')
|
||||||
|
speed = ('🐌' if self.msecs > 1000 else '') # Snail icon for run times over a second
|
||||||
|
return f'{self.n:3}: {self.title:40} {self.msecs:6,d} msec ⇒ {self.got:<16} {check} {speed}'
|
||||||
|
|
||||||
|
def runs() -> None:
|
||||||
|
"""Summary report on all the runs."""
|
||||||
|
T = [answer.msecs / 1000 for answer in RUNS.values()]
|
||||||
|
print(f'Problems: {len(T)}\n'
|
||||||
|
f'Run time in seconds: total: {sum(T):.1f}, max: {max(T):.1f}, '
|
||||||
|
f'mean: {mean(T):.3f}, median: {median(T):.3f}\n')
|
||||||
|
for i in sorted(RUNS):
|
||||||
|
print(RUNS[i])
|
||||||
|
|
||||||
|
#### Expected answers
|
||||||
|
|
||||||
|
EXPECTED = {
|
||||||
|
1: 233168, 2: 4613732, 3: 6857, 4: 906609, 5: 232792560, 6: 25164150,
|
||||||
|
7: 104743, 8: 23514624000, 9: 31875000, 10: 142913828922, 11: 70600674,
|
||||||
|
12: 76576500, 13: 5537376230, 14: 837799, 15: 137846528820, 16: 1366,
|
||||||
|
17: 21124, 18: 1074, 19: 171, 20: 648, 21: 31626, 22: 871198282,
|
||||||
|
23: 4179871, 24: 2783915460, 25: 4782, 26: 983, 27: -59231, 28: 669171001,
|
||||||
|
29: 9183, 30: 443839, 31: 73682, 32: 45228, 33: 100, 34: 40730, 35: 55,
|
||||||
|
36: 872187, 37: 748317, 38: 932718654, 39: 840, 40: 210, 41: 7652413,
|
||||||
|
42: 162, 43: 16695334890, 44: 5482660, 45: 1533776805, 46: 5777,
|
||||||
|
47: 134043, 48: 9110846700, 49: 296962999629, 50: 997651, 51: 121313,
|
||||||
|
52: 142857, 53: 4075, 54: 376, 55: 249, 56: 972, 57: 153, 58: 26241,
|
||||||
|
59: 107359, 60: 26033, 61: 28684, 62: 127035954683, 63: 49, 64: 1322,
|
||||||
|
65: 272, 66: 661, 67: 7273, 68: 6531031914842725, 69: 510510, 70: 8319823,
|
||||||
|
71: 428570, 72: 303963552391, 73: 7295372, 74: 402, 75: 161667,
|
||||||
|
76: 190569291, 77: 71, 78: 55374, 79: 73162890, 80: 40886, 81: 427337,
|
||||||
|
82: 260324, 83: 425185, 84: 101524, 85: 2772, 86: 1818, 87: 1097343,
|
||||||
|
88: 7587457, 89: 743, 90: 1217, 91: 14234, 92: 8581146, 93: 1258,
|
||||||
|
94: 518408346, 95: 14316, 96: 24702, 97: 8739992577, 98: 18769, 99: 709,
|
||||||
|
100: 756872327473,
|
||||||
|
}
|
||||||
|
|
||||||
|
#### Data
|
||||||
|
|
||||||
|
#### 13 problems have data from a file
|
||||||
|
#### 4 problems have data mentioned in the problem description and copied here
|
||||||
|
|
||||||
def read_data(filename) -> str:
|
def read_data(filename) -> str:
|
||||||
"""Read a file from the data/ subdirectory and return the contents as a stripped string."""
|
"""Read a file from the data/ subdirectory and return the contents as a stripped string."""
|
||||||
@@ -189,24 +252,3 @@ DATA = {
|
|||||||
53503534226472524250874054075591789781264330331690
|
53503534226472524250874054075591789781264330331690
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECTED = {
|
|
||||||
1: 233168, 2: 4613732, 3: 6857, 4: 906609, 5: 232792560, 6: 25164150,
|
|
||||||
7: 104743, 8: 23514624000, 9: 31875000, 10: 142913828922, 11: 70600674,
|
|
||||||
12: 76576500, 13: 5537376230, 14: 837799, 15: 137846528820, 16: 1366,
|
|
||||||
17: 21124, 18: 1074, 19: 171, 20: 648, 21: 31626, 22: 871198282,
|
|
||||||
23: 4179871, 24: 2783915460, 25: 4782, 26: 983, 27: -59231, 28: 669171001,
|
|
||||||
29: 9183, 30: 443839, 31: 73682, 32: 45228, 33: 100, 34: 40730, 35: 55,
|
|
||||||
36: 872187, 37: 748317, 38: 932718654, 39: 840, 40: 210, 41: 7652413,
|
|
||||||
42: 162, 43: 16695334890, 44: 5482660, 45: 1533776805, 46: 5777,
|
|
||||||
47: 134043, 48: 9110846700, 49: 296962999629, 50: 997651, 51: 121313,
|
|
||||||
52: 142857, 53: 4075, 54: 376, 55: 249, 56: 972, 57: 153, 58: 26241,
|
|
||||||
59: 107359, 60: 26033, 61: 28684, 62: 127035954683, 63: 49, 64: 1322,
|
|
||||||
65: 272, 66: 661, 67: 7273, 68: 6531031914842725, 69: 510510, 70: 8319823,
|
|
||||||
71: 428570, 72: 303963552391, 73: 7295372, 74: 402, 75: 161667,
|
|
||||||
76: 190569291, 77: 71, 78: 55374, 79: 73162890, 80: 40886, 81: 427337,
|
|
||||||
82: 260324, 83: 425185, 84: 101524, 85: 2772, 86: 1818, 87: 1097343,
|
|
||||||
88: 7587457, 89: 743, 90: 1217, 91: 14234, 92: 8581146, 93: 1258,
|
|
||||||
94: 518408346, 95: 14316, 96: 24702, 97: 8739992577, 98: 18769, 99: 709,
|
|
||||||
100: 756872327473,
|
|
||||||
}
|
|
||||||
@@ -34,8 +34,11 @@ notebooks = {
|
|||||||
('Advent of Code 2017', 2017, 'Advent-2017.ipynb', 'Puzzle site with a coding puzzle each day of Advent, December 2017'),
|
('Advent of Code 2017', 2017, 'Advent-2017.ipynb', 'Puzzle site with a coding puzzle each day of Advent, December 2017'),
|
||||||
('Advent of Code 2016', 2016, 'Advent-2016.ipynb', 'Puzzle site with a coding puzzle each day of Advent, December 2016'),
|
('Advent of Code 2016', 2016, 'Advent-2016.ipynb', 'Puzzle site with a coding puzzle each day of Advent, December 2016'),
|
||||||
('Advent of Code Utilities', 2022, 'AdventUtils.ipynb', 'Utility functions for Advent of Code puzzles'),
|
('Advent of Code Utilities', 2022, 'AdventUtils.ipynb', 'Utility functions for Advent of Code puzzles'),
|
||||||
('Project Euler 1–100', 2026, 'Euler.ipynb', 'Solutions to the first 100 Project Euler math/programming problems'),
|
('Project Euler #1–100 by a Human', 2026, 'Euler.ipynb', 'Solutions to the first 100 Project Euler math/programming problems'),
|
||||||
('Project Euler #3: Largest prime factor', 2026, 'Euler3.ipynb', 'For beginner programmers: How to find the largest prime factor of a number'),
|
('Project Euler #1–100 by Fable LLM', 2026, 'Euler-Fable.ipynb', 'Solutions to Project Euler math/programming problems by Claude Fable LLM'),
|
||||||
|
('Project Euler #1–100 by Opus LLM', 2026, 'Euler-Opus.ipynb', 'Solutions to Project Euler math/programming problems by Claude Opus LLM'),
|
||||||
|
('Project Euler #1–100 by Kimi LLM', 2026, 'Euler-Kimi.ipynb', 'Solutions to Project Euler math/programming problems by Kimi LLM'),
|
||||||
|
('Largest prime factor', 2026, 'Euler3.ipynb', 'For beginner programmers: How to find the largest prime factor of a number. Project Euler #3.'),
|
||||||
],
|
],
|
||||||
|
|
||||||
'Probability and Uncertainty': [
|
'Probability and Uncertainty': [
|
||||||
|
|||||||
Reference in New Issue
Block a user