Compare commits

...

7 Commits

Author SHA1 Message Date
Peter Norvig d5d31f932d
Add files via upload 2024-02-20 23:01:37 -08:00
Peter Norvig 1ae17ba5b6
Add files via upload 2024-02-20 15:51:22 -08:00
Peter Norvig f26e74abb6
Update pytudes.py 2024-02-20 15:05:02 -08:00
Peter Norvig 334a041609
Update README.md 2024-02-20 14:55:44 -08:00
Peter Norvig 0b9c561a5f
Update for end of 2023 2024-02-20 11:40:54 -08:00
Peter Norvig 48345cd9d6
Rename Advent of Code.ipynb to Advent-2016.ipynb 2024-02-20 11:25:17 -08:00
Peter Norvig 44926e9569
Rename Advent 2017.ipynb to Advent-2017.ipynb 2024-02-20 11:24:56 -08:00
10 changed files with 8759 additions and 5921 deletions

View File

@ -26,14 +26,17 @@ For each notebook you can hover or click on the title, or click one of the lette
|Run|Year|Recent (2022)|
|Run|Year|Recent (20222024)|
|---|---|---|
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/AlphaCode.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAlphaCode.ipynb)[G](ipynb/AlphaCode.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAlphaCode.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/AlphaCode.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/AlphaCode.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/AlphaCode.ipynb" title="Analysis of AlphaCode's automated solution to a coding problem">AlphaCode Automated Programming</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/OneLetterOff.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FOneLetterOff.ipynb)[G](ipynb/OneLetterOff.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FOneLetterOff.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/OneLetterOff.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/OneLetterOff.ipynb) | 2023 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/OneLetterOff.ipynb" title="Word game; use of a large language model to generate clues.">One Letter Off</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FMenu.ipynb)[G](ipynb/Menu.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FMenu.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb" title="Efficiently Selecting Names from a Menu, by typing characters and arrows">Selecting Names from a Menu</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2023.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent-2023.ipynb)[G](ipynb/Advent-2023.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent-2023.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2023.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent-2023.ipynb) | 2023 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2023.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2022">Advent of Code 2023</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2022.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent-2022.ipynb)[G](ipynb/Advent-2022.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent-2022.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2022.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent-2022.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2022.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2022">Advent of Code 2022</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdventUtils.ipynb)[G](ipynb/AdventUtils.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdventUtils.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb" title="Utility functions for Advent of Code puzzles">Advent of Code Utilities</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Wordle.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FWordle.ipynb)[G](ipynb/Wordle.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FWordle.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Wordle.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Wordle.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Wordle.ipynb" title="A simple human-usable strategy to always win at Wordle. And an analysis of 2-guess wins">Winning Wordle</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Overtime.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FOvertime.ipynb)[G](ipynb/Overtime.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FOvertime.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Overtime.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Overtime.ipynb) | 2023 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Overtime.ipynb" title="In American Football, which team has the advantage in overtime?">Overtime in American Football</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FGoldberg.ipynb)[G](ipynb/Goldberg.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FGoldberg.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb" title="A re-implementation in Python 3 of Yoav Goldberg's unreasonably effective character-level n-gram language model.">Goldberg's Character-level Language Model</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Wordle.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FWordle.ipynb)[G](ipynb/Wordle.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FWordle.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Wordle.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Wordle.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Wordle.ipynb" title="A simple human-usable strategy to always win at Wordle. And an analysis of 2-guess wins">Winning Wordle</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Anigrams.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAnigrams.ipynb)[G](ipynb/Anigrams.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAnigrams.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Anigrams.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Anigrams.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Anigrams.ipynb" title="Finding the longest chain of anagrams that each add one letter">Anigrams: Word Chains</a> |
@ -47,24 +50,41 @@ For each notebook you can hover or click on the title, or click one of the lette
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Life.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FLife.ipynb)[G](ipynb/Life.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FLife.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Life.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Life.ipynb) | 2017 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Life.ipynb" title="The cellular automata zero-player game">Conway's Game of Life</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Maze.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FMaze.ipynb)[G](ipynb/Maze.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FMaze.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Maze.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Maze.ipynb) | 2020 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Maze.ipynb" title="Make a maze by generating a random tree superimposed on a grid and solve it">Generating and Solving Mazes</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Konane.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FKonane.ipynb)[G](ipynb/Konane.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FKonane.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Konane.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Konane.ipynb) | 2021 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Konane.ipynb" title="Solving the game of Konane (Hawaiian checkers).">Mel's Konane Board</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FMenu.ipynb)[G](ipynb/Menu.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FMenu.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb" title="Efficiently Selecting Names from a Menu, by typing characters and arrows">Selecting Names from a Menu</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/OneLetterOff.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FOneLetterOff.ipynb)[G](ipynb/OneLetterOff.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FOneLetterOff.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/OneLetterOff.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/OneLetterOff.ipynb) | 2023 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/OneLetterOff.ipynb" title="Word game; use of a large language model to generate clues.">One Letter Off</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/PhotoFocalLengths.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FPhotoFocalLengths.ipynb)[G](ipynb/PhotoFocalLengths.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FPhotoFocalLengths.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/PhotoFocalLengths.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/PhotoFocalLengths.ipynb) | 2020 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/PhotoFocalLengths.ipynb" title="Generate charts of what focal lengths were used on a photo trip">Photo Focal Lengths</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Pickleball.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FPickleball.ipynb)[G](ipynb/Pickleball.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FPickleball.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Pickleball.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Pickleball.ipynb) | 2018 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Pickleball.ipynb" title="Scheduling a doubles tournament fairly and efficiently">Pickleball Tournament</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Project%20Euler%20Utils.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FProject%20Euler%20Utils.ipynb)[G](ipynb/Project%20Euler%20Utils.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FProject%20Euler%20Utils.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Project%20Euler%20Utils.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Project%20Euler%20Utils.ipynb) | 2017 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Project%20Euler%20Utils.ipynb" title="My utility functions for the Project Euler problems, including `Primes` and `Factors`">Project Euler Utilities</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FMenu.ipynb)[G](ipynb/Menu.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FMenu.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Menu.ipynb" title="Efficiently Selecting Names from a Menu, by typing characters and arrows">Selecting Names from a Menu</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Electoral%20Votes.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FElectoral%20Votes.ipynb)[G](ipynb/Electoral%20Votes.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FElectoral%20Votes.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Electoral%20Votes.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Electoral%20Votes.ipynb) | 2020 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Electoral%20Votes.ipynb" title="How many electoral votes would Trump get if he wins the state where he has positive net approval?">Tracking Trump: Electoral Votes</a> |
|Run|Year|Advent of Code|
|---|---|---|
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2023.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent-2023.ipynb)[G](ipynb/Advent-2023.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent-2023.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2023.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent-2023.ipynb) | 2023 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2023.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2022">Advent of Code 2023</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2022.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent-2022.ipynb)[G](ipynb/Advent-2022.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent-2022.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2022.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent-2022.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2022.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2022">Advent of Code 2022</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2021.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent-2021.ipynb)[G](ipynb/Advent-2021.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent-2021.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2021.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent-2021.ipynb) | 2021 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2021.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2021">Advent of Code 2021</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2020.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent-2020.ipynb)[G](ipynb/Advent-2020.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent-2020.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2020.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent-2020.ipynb) | 2020 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2020.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2020">Advent of Code 2020</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2018.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent-2018.ipynb)[G](ipynb/Advent-2018.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent-2018.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2018.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent-2018.ipynb) | 2018 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2018.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2018">Advent of Code 2018</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent%202017.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent%202017.ipynb)[G](ipynb/Advent%202017.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent%202017.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent%202017.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent%202017.ipynb) | 2017 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent%202017.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2017">Advent of Code 2017</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent%20of%20Code.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent%20of%20Code.ipynb)[G](ipynb/Advent%20of%20Code.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent%20of%20Code.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent%20of%20Code.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent%20of%20Code.ipynb) | 2016 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent%20of%20Code.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2016">Advent of Code 2016</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2017.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent-2017.ipynb)[G](ipynb/Advent-2017.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent-2017.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2017.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent-2017.ipynb) | 2017 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2017.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2017">Advent of Code 2017</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2016.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdvent-2016.ipynb)[G](ipynb/Advent-2016.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdvent-2016.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Advent-2016.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Advent-2016.ipynb) | 2016 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Advent-2016.ipynb" title="Puzzle site with a coding puzzle each day for Advent 2016">Advent of Code 2016</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAdventUtils.ipynb)[G](ipynb/AdventUtils.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAdventUtils.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/AdventUtils.ipynb" title="Utility functions for Advent of Code puzzles">Advent of Code Utilities</a> |
|Run|Year|Probability and Uncertainty|
|---|---|---|
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Overtime.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FOvertime.ipynb)[G](ipynb/Overtime.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FOvertime.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Overtime.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Overtime.ipynb) | 2023 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Overtime.ipynb" title="In American Football, which team has the advantage in overtime?">Overtime in American Football</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FGoldberg.ipynb)[G](ipynb/Goldberg.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FGoldberg.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb" title="A re-implementation in Python 3 of Yoav Goldberg's unreasonably effective character-level n-gram language model.">Goldberg's Character-level Language Model</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Probability.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FProbability.ipynb)[G](ipynb/Probability.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FProbability.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Probability.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Probability.ipynb) | 2018 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Probability.ipynb" title="Code and examples of the basic principles of Probability Theory">A Concrete Introduction to Probability</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/ProbabilityParadox.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FProbabilityParadox.ipynb)[G](ipynb/ProbabilityParadox.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FProbabilityParadox.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/ProbabilityParadox.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/ProbabilityParadox.ipynb) | 2016 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/ProbabilityParadox.ipynb" title="Some classic paradoxes in Probability Theory, and how to think about disagreements">Probability, Paradox, and the Reasonable Person Principle</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/ProbabilitySimulation.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FProbabilitySimulation.ipynb)[G](ipynb/ProbabilitySimulation.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FProbabilitySimulation.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/ProbabilitySimulation.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/ProbabilitySimulation.ipynb) | 2020 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/ProbabilitySimulation.ipynb" title="When the sample space is too complex, simulations can estimate probabilities">Estimating Probabilities with Simulations</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Coin%20Flip.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FCoin%20Flip.ipynb)[G](ipynb/Coin%20Flip.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FCoin%20Flip.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Coin%20Flip.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Coin%20Flip.ipynb) | 2019 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Coin%20Flip.ipynb" title="How to beat the Devil at his own game">The Devil and the Coin Flip Game</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Dice%20Baseball.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FDice%20Baseball.ipynb)[G](ipynb/Dice%20Baseball.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FDice%20Baseball.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Dice%20Baseball.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Dice%20Baseball.ipynb) | 2020 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Dice%20Baseball.ipynb" title="Simulating baseball games">Dice Baseball</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Economics.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FEconomics.ipynb)[G](ipynb/Economics.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FEconomics.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Economics.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Economics.ipynb) | 2018 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Economics.ipynb" title="A simulation of a simple economic game">Economics Simulation</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/poker.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2Fpoker.ipynb)[G](ipynb/poker.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2Fpoker.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/poker.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/poker.ipynb) | 2012 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/poker.ipynb" title="How do we decide which poker hand wins? Several variants of poker are considered">Poker Hand Ranking</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/risk.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2Frisk.ipynb)[G](ipynb/risk.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2Frisk.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/risk.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/risk.ipynb) | 2020 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/risk.ipynb" title="Determining who is likely to win an interminably long game of Risk">The Unfinished Game .... of Risk</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/WWW.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FWWW.ipynb)[G](ipynb/WWW.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FWWW.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/WWW.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/WWW.ipynb) | 2019 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/WWW.ipynb" title="Computing the probability of winning the NBA title, for my home town Warriors, or any other team">WWW: Who Will Win (NBA Title)?</a> |
|Run|Year|Logic and Number Puzzles|
|---|---|---|
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Cryptarithmetic.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FCryptarithmetic.ipynb)[G](ipynb/Cryptarithmetic.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FCryptarithmetic.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Cryptarithmetic.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Cryptarithmetic.ipynb) | 2014 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Cryptarithmetic.ipynb" title="Substitute digits for letters and make NUM + BER = PLAY">Cryptarithmetic</a> |
@ -103,20 +123,6 @@ For each notebook you can hover or click on the title, or click one of the lette
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/xkcd-Name-Dominoes.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2Fxkcd-Name-Dominoes.ipynb)[G](ipynb/xkcd-Name-Dominoes.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2Fxkcd-Name-Dominoes.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/xkcd-Name-Dominoes.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/xkcd-Name-Dominoes.ipynb) | 2018 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/xkcd-Name-Dominoes.ipynb" title="Lay out dominoes legally; the dominoes have people names, not numbers">xkcd 1970: Name Dominoes</a> |
|Run|Year|Probability and Uncertainty|
|---|---|---|
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FGoldberg.ipynb)[G](ipynb/Goldberg.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FGoldberg.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Goldberg.ipynb" title="A re-implementation in Python 3 of Yoav Goldberg's unreasonably effective character-level n-gram language model.">Goldberg's Character-level Language Model</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Probability.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FProbability.ipynb)[G](ipynb/Probability.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FProbability.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Probability.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Probability.ipynb) | 2018 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Probability.ipynb" title="Code and examples of the basic principles of Probability Theory">A Concrete Introduction to Probability</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/ProbabilityParadox.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FProbabilityParadox.ipynb)[G](ipynb/ProbabilityParadox.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FProbabilityParadox.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/ProbabilityParadox.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/ProbabilityParadox.ipynb) | 2016 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/ProbabilityParadox.ipynb" title="Some classic paradoxes in Probability Theory, and how to think about disagreements">Probability, Paradox, and the Reasonable Person Principle</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/ProbabilitySimulation.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FProbabilitySimulation.ipynb)[G](ipynb/ProbabilitySimulation.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FProbabilitySimulation.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/ProbabilitySimulation.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/ProbabilitySimulation.ipynb) | 2020 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/ProbabilitySimulation.ipynb" title="When the sample space is too complex, simulations can estimate probabilities">Estimating Probabilities with Simulations</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Coin%20Flip.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FCoin%20Flip.ipynb)[G](ipynb/Coin%20Flip.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FCoin%20Flip.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Coin%20Flip.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Coin%20Flip.ipynb) | 2019 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Coin%20Flip.ipynb" title="How to beat the Devil at his own game">The Devil and the Coin Flip Game</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Dice%20Baseball.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FDice%20Baseball.ipynb)[G](ipynb/Dice%20Baseball.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FDice%20Baseball.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Dice%20Baseball.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Dice%20Baseball.ipynb) | 2020 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Dice%20Baseball.ipynb" title="Simulating baseball games">Dice Baseball</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Economics.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FEconomics.ipynb)[G](ipynb/Economics.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FEconomics.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Economics.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Economics.ipynb) | 2018 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Economics.ipynb" title="A simulation of a simple economic game">Economics Simulation</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/poker.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2Fpoker.ipynb)[G](ipynb/poker.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2Fpoker.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/poker.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/poker.ipynb) | 2012 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/poker.ipynb" title="How do we decide which poker hand wins? Several variants of poker are considered">Poker Hand Ranking</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/risk.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2Frisk.ipynb)[G](ipynb/risk.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2Frisk.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/risk.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/risk.ipynb) | 2020 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/risk.ipynb" title="Determining who is likely to win an interminably long game of Risk">The Unfinished Game .... of Risk</a> |
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/WWW.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FWWW.ipynb)[G](ipynb/WWW.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FWWW.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/WWW.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/WWW.ipynb) | 2019 | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/WWW.ipynb" title="Computing the probability of winning the NBA title, for my home town Warriors, or any other team">WWW: Who Will Win (NBA Title)?</a> |
|Run|Year|The Riddler (from 538)|
|---|---|---|
| [C](https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Anigrams.ipynb)[D](https://beta.deepnote.org/launch?template=python_3.6&url=https%3A%2F%2Fgithub.com%2Fnorvig%2Fpytudes%2Fblob%2Fmain%2Fipynb%2FAnigrams.ipynb)[G](ipynb/Anigrams.ipynb)[M](https://mybinder.org/v2/gh/norvig/pytudes/main?filepath=ipynb%2FAnigrams.ipynb)[N](https://nbviewer.jupyter.org/github/norvig/pytudes/blob/main/ipynb/Anigrams.ipynb)[S](https://studiolab.sagemaker.aws/import/github/norvig/pytudes/blob/main/ipynb/Anigrams.ipynb) | <u>2022</u> | <a href="https://colab.research.google.com/github/norvig/pytudes/blob/main/ipynb/Anigrams.ipynb" title="Finding the longest chain of anagrams that each add one letter">Anigrams: Word Chains</a> |

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
@ -31,24 +31,24 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Reading Data: `rides` and `yearly`\n",
"# Reading Data: `rides`, `yearly`, and `daily`\n",
"\n",
"I saved a bunch of my recorded [Strava](https://www.strava.com/athletes/575579) rides, most of them longer than 25 miles, as [`bikerides.tsv`](bikerides.tsv). The columns are: the date; the year; a title; the elapsed time of the ride; the length of the ride in miles; and the total climbing in feet, e.g.: \n",
"I saved a bunch of my recorded [Strava](https://www.strava.com/athletes/575579) rides, most of them longer than 25 miles, as [`bikerides.tsv`](bikerides.tsv). The tab-separated columns are: the date; the year; a title; the elapsed time of the ride; the length of the ride in miles; and the total climbing in feet, e.g.: \n",
"\n",
" Mon, 10/5\t2020\tHalf way around the bay on bay trail\t6:26:35\t80.05\t541\n",
" Mon, 10/5/2020\tHalf way around the bay on bay trail\t6:26:35\t80.05\t541\n",
" \n",
"I parse the file into the pandas dataframe `rides`, adding derived columns for miles per hour, vertical meters climbed per hour (VAM), grade in feet per mile, grade in percent, and kilometers ridden:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 119,
"metadata": {},
"outputs": [],
"source": [
"def parse_rides(lines):\n",
" \"\"\"Parse a bikerides.tsv file.\"\"\"\n",
" return drop_index(add_columns(pd.read_table(lines, comment='#',\n",
" return drop_index(add_ride_columns(pd.read_table(lines, comment='#',\n",
" converters=dict(hours=parse_hours, feet=parse_int))))\n",
"\n",
"def parse_hours(time: str) -> float: \n",
@ -57,18 +57,20 @@
" for i, x in enumerate(reversed(time.split(':'))))\n",
" return round(hrs, 2)\n",
"\n",
"def parse_int(field: str) -> int: return int(field.replace(',', ''))\n",
"def parse_int(field: str) -> int: return int(field.replace(',', '').replace('ft', '').replace('mi', ''))\n",
"\n",
"def add_columns(rides) -> pd.DataFrame:\n",
"def add_ride_columns(rides) -> pd.DataFrame:\n",
" \"\"\"Compute new columns from existing ones.\"\"\"\n",
" mi, hr, ft = rides['miles'], rides['hours'], rides['feet']\n",
" if 'date' in rides and 'year' not in rides:\n",
" rides.insert(1, \"year\", [int(str(d).split('/')[-1]) for d in rides['date'].tolist()])\n",
" return rides.assign(\n",
" mph=round(mi / hr, 2),\n",
" vam=round(ft / hr / 3.28084),\n",
" fpm=round(ft / mi),\n",
" fpmi=round(ft / mi),\n",
" pct=round(ft / mi * 100 / 5280, 2),\n",
" kms=round(mi * 1.609, 2),\n",
" km_up=round(ft * 0.0003048, 1))\n",
" meters=round(ft * 0.3048))\n",
"\n",
"def drop_index(frame) -> pd.DataFrame:\n",
" \"\"\"Drop the index column.\"\"\"\n",
@ -78,15 +80,17 @@
},
{
"cell_type": "code",
"execution_count": 65,
"execution_count": 125,
"metadata": {},
"outputs": [],
"source": [
"rides = parse_rides(open('bikerides.tsv'))\n",
"yearly = parse_rides(open('bikeyears.tsv')).drop(columns=['date', 'title'])\n",
"\n",
"yearly = parse_rides(open('bikeyears.tsv')).drop(columns='date')\n",
"\n",
"daily = yearly.copy()\n",
"for name in 'hours miles feet kms km_up'.split():\n",
" daily[name] = round(daily[name].map(lambda x: x / 350), 3 if name == 'km_up' else 1)"
"for name in 'hours miles feet kms meters'.split():\n",
" daily[name] = round(daily[name].map(lambda x: x / (6 * 52)), 1)"
]
},
{
@ -106,7 +110,7 @@
},
{
"cell_type": "code",
"execution_count": 41,
"execution_count": 36,
"metadata": {},
"outputs": [],
"source": [
@ -118,30 +122,12 @@
" title, mi, ft, *times = segment.split(',')[:5]\n",
" for time in times:\n",
" records.append((title, parse_hours(time), float(mi), parse_int(ft)))\n",
" return add_columns(pd.DataFrame(records, columns=('title', 'hours', 'miles', 'feet')))"
" return add_ride_columns(pd.DataFrame(records, columns=('title', 'hours', 'miles', 'feet')))"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [],
"source": [
"segments = parse_segments(open('bikesegments.csv'))"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [],
"source": [
"places = pd.read_table(open('bikeplaceshort.csv'), sep=',', comment='#')"
]
},
{
"cell_type": "code",
"execution_count": 50,
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
@ -160,18 +146,25 @@
},
{
"cell_type": "code",
"execution_count": 57,
"execution_count": 59,
"metadata": {},
"outputs": [],
"source": [
"segments = parse_segments(open('bikesegments.csv'))\n",
"\n",
"places = drop_index(pd.read_table(open('bikeplaceshort.csv'), sep=',', comment='#'))\n",
"\n",
"tiles = drop_index(pd.DataFrame(columns='date square cluster total comment'.split(), data=[\n",
" ('06/30/2023', 13, 689, 2640, 'Rides in east Bay!9298603815'),\n",
" ('04/14/2023', 13, 630, 2595, 'Black Sands Beach connects Marin to max cluster!8891171008'),\n",
" ('03/04/2023', 13, 583, 2574, 'Almaden rides connects Gilroy to max cluster!8654437264'),\n",
" ('10/22/2022', 13, 396, 2495, 'Alviso levees to get to 13x13 max square!8003921626'),\n",
" ('10/16/2022', 12, 393, 2492, 'Milpitas ride connects East Bay to max cluster!7974994605'),\n",
" ('09/08/2022', 11, 300, 2487, 'First started tracking tiles')])\n",
" ).style.format({'comment': make_clickable, 'date': link_date})"
" ('01/01/2024', 14, 1056, 3105, 'Start of this year'),\n",
" ('12/08/2023', 14, 1042, 3084, 'Benicia ride connects East Bay and Napa clusters!10350071201'),\n",
" ('11/05/2023', 14, 932, 2914, 'Alum Rock ride gets 14x14 max square!8850905872'),\n",
" ('06/30/2023', 13, 689, 2640, 'Rides in east Bay fill in holes!9298603815'),\n",
" ('04/14/2023', 13, 630, 2595, 'Black Sands Beach low-tide hike connects Marin to max cluster!8891171008'),\n",
" ('03/04/2023', 13, 583, 2574, 'Almaden rides connects Gilroy to max cluster!8654437264'),\n",
" ('10/22/2022', 13, 396, 2495, 'Alviso levees to get to 13x13 max square!8003921626'),\n",
" ('10/16/2022', 12, 393, 2492, 'Milpitas ride connects East Bay to max cluster!7974994605'),\n",
" ('09/08/2022', 11, 300, 2487, 'First started tracking tiles')])\n",
" ).style.format({'comment': make_clickable, 'date': link_date})"
]
},
{
@ -183,7 +176,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 41,
"metadata": {},
"outputs": [],
"source": [
@ -216,7 +209,7 @@
" \"\"\"Given a ride distance in miles and total climb in feet, estimate time in minutes.\"\"\"\n",
" return round(60 * miles / estimator(feet / miles))\n",
"\n",
"def top(frame, field, n=20): return frame.sort_values(field, ascending=False).head(n)"
"def top(frame, field, n=20): return drop_index(frame.sort_values(field, ascending=False).head(n))"
]
},
{
@ -228,23 +221,33 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 101,
"metadata": {},
"outputs": [],
"source": [
"def mapl(f, *values): return list(map(f, *values))\n",
"\n",
"def wandering(places=places, by=['pct']):\n",
" \"All those who wander are not lost.\" # Also try by=['cat', 'pct']\n",
" frame = places.sort_values(by=by, ascending=('pct' not in by))\n",
" M = 1_000_000\n",
" for i, (name, miles, county, pct) in frame.iterrows():\n",
" # Some fiddling to get the format right\n",
" p = f'{pct:.1f}' if (pct > 0.1) else f'{pct:.3f}'\n",
" mymiles = pct / 100 * miles\n",
" done = f'{rounded(mymiles)}/{rounded(miles)} mi'\n",
" togo = next((f'{rounded(target / 100 * miles - mymiles):>5} mi for {target}%' \n",
" for target in (0.02, 0.1, 0.2, 1, 2, 25, 50, 90, 99)\n",
" if mymiles < target / 100 * miles), '')\n",
" print(f'{county} {p:>5}% {name:25} {done:>15} {togo}') \n",
" F = drop_index(places.sort_values(by=by, ascending=('pct' not in by)))\n",
" pd.set_option('display.max_rows', None)\n",
" return pd.DataFrame(\n",
" {'pct': [f'{p:.1f}%' if (p > 1) else f'{p:.3f}%' for p in F['pct']],\n",
" 'county': F['county'],\n",
" 'name': F['name'],\n",
" 'total': F['miles'],\n",
" 'done': mapl(rounded, F['miles'] * F['pct'] / 100),\n",
" 'to next badge': mapl(to_go, F['pct'], F['miles'])})\n",
"\n",
"\n",
"def to_go(pct, miles, targets=(0.02, 0.1, 0.2, 1, 2, 25, 50, 90, 99)):\n",
" \"\"\"Describe next target to hit to get a badge.\"\"\"\n",
" done = pct * miles / 100\n",
" return next((f'{rounded(target / 100 * miles - done):>5} mi to {target}%' \n",
" for target in targets\n",
" if done < target / 100 * miles), \n",
" '')\n",
" \n",
"def rounded(x: float) -> str: \n",
" \"\"\"Round x to 3 spaces wide (if possible).\"\"\"\n",
@ -263,32 +266,36 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"def make_leaders(data):\n",
" \"\"\"Make a dataframe of leaders in two counties.\"\"\"\n",
" leaders = pd.DataFrame(data, columns=['Name', 'Initials', 'SMC %', 'SCC %', 'Front?'])\n",
" leaders = pd.DataFrame(data, columns=['Name', 'Initials', 'SMC %', 'SCC %'])\n",
" leaders['SMC miles'] = [round(2814 * d[2] / 100) for d in data]\n",
" leaders['SCC miles'] = [round(7569 * d[3] / 100) for d in data]\n",
" leaders['Total miles'] = leaders['SMC miles'] + leaders['SCC miles']\n",
" leaders['Avg %'] = (leaders['SMC %'] + leaders['SCC %']) / 2\n",
" return drop_index(leaders.sort_values('Avg %', ascending=False))\n",
"\n",
"leaders = make_leaders([ # Data as of Sept 20, 2023 (Name, Initials, SMC, SCC, Frontier?)\n",
" ('Barry Mann', 'BM', 76.97, 30.21, 1), ('Jason Molenda', 'JM', 7.13, 55.39, 1), \n",
" ('Peter Norvig', 'PN', 61.56, 32.8, 1), ('Brian Feinberg', 'BF', 32.5, 43.68, 1),\n",
" ('Jim Brooks', 'JB', 4.23, 44.36, 0), ('Megan Gardner', 'MG', 97.62, 8.69, 1),\n",
" ('Matthew Ring', 'MR', 78.85, 1.48, 0), ('Elliot Hoff', 'EF', 52.88, 8.14, 0)])\n",
"leaders = make_leaders([ # Data as of Jan 3, 2024 (Name, Initials, SMC, SCC)\n",
" ('Megan Gardner', 'MG', 99.01, 13.6),\n",
" ('Barry Mann', 'BM', 77.41, 30.38), \n",
" ('Peter Norvig', 'PN', 63.5, 33.0),\n",
" ('Brian Feinberg', 'BF', 32.5, 43.9),\n",
" ('Jason Molenda', 'JM', 7.56, 56.25) \n",
" ])\n",
" \n",
"def pareto_front(leaders):\n",
" ax = leaders.plot('SMC %', 'SCC %', grid=True, kind='scatter')\n",
" front = sorted((x, y) for i, (_, _, x, y, f, *_) in leaders.iterrows() if f)\n",
" ax = leaders.plot('SMC %', 'SCC %', kind='scatter')\n",
" front = sorted((x, y) for i, (_, _, x, y, *_) in leaders.iterrows())\n",
" ax.plot(*zip(*front), ':'); ax.axis('square'); grid()\n",
" ax.set_xlabel('San Mateo County %')\n",
" ax.set_ylabel('Santa Clara County %')\n",
" for i, (name, initials, x, y, *_) in leaders.iterrows():\n",
" ax.text(x - 2, y + 2, initials)\n",
" return leaders.drop(columns=['Front?'])"
" return leaders"
]
},
{
@ -300,7 +307,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 45,
"metadata": {},
"outputs": [],
"source": [
@ -314,16 +321,14 @@
" \"\"\"The number of rides needed to reach an Eddington number target.\"\"\"\n",
" return target - sum(distances >= target)\n",
"\n",
"def Ed_gaps(rides, E_km=100, E_mi=67, N=11) -> dict:\n",
"def Ed_gaps(rides, E_km=103, E_mi=69, N=9) -> dict:\n",
" \"\"\"A table of gaps to Eddington numbers by year.\"\"\"\n",
" data = [(E_km + d, sum(rides.kms >= E_km + d), Ed_gap(rides.kms, E_km + d), \n",
" E_mi + d, sum(rides.miles >= E_mi + d), Ed_gap(rides.miles, E_mi + d))\n",
" data = [(E_km + d, Ed_gap(rides.kms, E_km + d), E_mi + d, Ed_gap(rides.miles, E_mi + d))\n",
" for d in range(N)]\n",
" df = pd.DataFrame(data, columns=['kms', 'km rides', 'kms gap', \n",
" 'miles', 'miles rides', 'miles gap'])\n",
" df = pd.DataFrame(data, columns=['kms', 'kms gap', 'miles', 'miles gap'])\n",
" return drop_index(df)\n",
"\n",
"def Ed_progress(rides, years=range(2023, 2013, -1)) -> pd.DataFrame:\n",
"def Ed_progress(rides, years=range(2024, 2013, -1)) -> pd.DataFrame:\n",
" \"\"\"A table of Eddington numbers by year, and a plot.\"\"\"\n",
" def Ed(year, unit): return Ed_number(rides[rides['year'] <= year], unit)\n",
" data = [(y, Ed(y, 'kms'), Ed(y, 'miles')) for y in years]\n",

File diff suppressed because it is too large Load Diff

978
ipynb/Overtime.ipynb Normal file
View File

@ -0,0 +1,978 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "13d72a29-e929-4b88-8d4f-6db3154dec12",
"metadata": {},
"source": [
"<div style=\"text-align: right\" align=\"right\"><i>Peter Norvig<br> Feb 2024</i></div> \n",
"\n",
"# Probabilities for Overtime in the Super Bowl\n",
"\n",
"In American football, if the game is tied at the end of 60 minutes of play, an overtime period commences, with these rules:\n",
"\n",
"- There is a coin toss; the team that guesses right has the option of possessing the ball first or second.\n",
"- Both teams get one possession to attempt to score points.\n",
"- After those two possessions, if the score is still tied, the game continues and the next score wins the game.\n",
"\n",
"A recap of (most of) the scoring rules:\n",
"\n",
"- A team scores **3** points for kicking a **field goal**. \n",
"- A team scores **6** points for a **touchdown**. \n",
"- After scoring a touchdown, if the game is not over, a team has the option of trying for extra point(s): either **one** point (easy) or **two** points (harder).\n",
"\n",
"\n",
"\n",
"The 2024 Super Bowl went into overtime, and there was some criticism of San Francisco 49ers coach Kyle Shanahan, who, after winning the coin toss, elected to possess the ball first rather than second. As it turned out the 49ers scored a field goal and then the Chiefs scored a touchdown to win. If the 49ers had taken the ball second, and they had known that the Chiefs scored a touchdown, they could have gone for their own touchdown rather than the field goal, and perhaps tied or won the game. The first question is: Is it better to possess the ball first (team **A**) or second (team **B**)? There are two main points to consider:\n",
"\n",
"- **B** has the advantage of knowing **B**'s score on their first possession.\n",
"- **A** has the advantage that if the score is tied after each team has their first possession, **A** gets the ball next (third), and next score wins.\n",
"\n",
"The second question is: if a team scores a touchdown on their first possession, what should their strategy be for the extra point(s)? It sems like **A** should go for 1, because if they go for 2 and miss, then it is too easy for **B** to make a 1-point conversion and win. On the other hand, it seems that **B** should go for 2, because if they tie the score at 7-7, then it is too easy for **A** to score next and win.\n",
"\n",
"In this notebook I do a simulation to answer these two questions.\n",
"\n",
"\n",
"## Code to Simulate One Random Overtime Game\n",
"\n",
"Calling the function `overtime()` below runs a random simulation and returns a tuple of the two scores for team **A** and team **B**. Optionally, you can set certain probability parameters (they will be the same for both teams):\n",
"- **TD**: the probability of scoring a touchdown on a given possession, for both teams. (About 20%, by league average in recent years.)\n",
"- **FG**: the probability of scoring a field goal, for both teams. (About 25%.)\n",
"- **go**: the *additional* probability of scoring a touchdown for a team that must score a touchdown or losei.e., if team **A** scores a touchdown on their first possession, team **B** would never kick a field goal (or punt), in those situations they will instead go for a touchdown, which they get with probability **go**. (Set at 10%, but I'm not sure if that is a good estimate.)\n",
"- **one**: the probability of succesfully kicking a 1-point conversion attempt. (About 98%.)\n",
"- **two**: the probability of succesfully scoring on a 2-point conversion attempt. (About 48%.)\n",
"- **A_extra**: 1 or 2, denoting what **A** should try for if they score a touchdown on their first possession.\n",
"- **B_extra**: 1 or 2, denoting what **B** should try for if **A** scored 7 points on their first possession.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "890a789e-719f-4ca2-aa9e-f5384d7dfd80",
"metadata": {},
"outputs": [],
"source": [
"import random\n",
"from collections import Counter\n",
"Prob = float # The type for a probability, a number between 0 and 1.\n",
"\n",
"def overtime(TD=0.20, FG=0.25, go=0.10, one=0.98, two=0.48, A_extra=1, B_extra=2) -> tuple:\n",
" \"\"\"Given probabilities, play a random overtime and return (team_A_score, team_B_score).\n",
" Both teams have same probabilities:\n",
" TD: probability of scoring a touchdown on a 'normal' possession. \n",
" FG: probability of scoring a field goal on a 'normal' possession.\n",
" go: additional probability of scoring a touchdown, if you resolve not to kick.\n",
" one: probability of making a one-point conversion.\n",
" two: probability of making a two-point conversion.\n",
" A_extra: what team A goes for on the extra point.\n",
" B_extra: what team B goes for on the extra point (when behind by 1).\"\"\"\n",
" A = B = 0 # The scores of the two teams\n",
" possession = 1 # The number of possessions for each team\n",
" while A == B:\n",
" extra = (0 if possession > 1 else P(one, 1) if A_extra == 1 else P(two, 2))\n",
" A += score(TD, FG, extra)\n",
" if possession == 1 or A == B: # B gets a chance on their first possession, or if it is still tied.\n",
" extra = (0 if B + 6 > A else P(one, 1) if B + 6 == A or (B_extra == 1 and B + 7 == A) else P(two, 2))\n",
" B += (score(TD + go, 0, extra) if A - B > 3 # Must go for TD if behind by more than 3\n",
" else \n",
" score(TD, FG, 0))\n",
" possession += 1\n",
" return A, B\n",
"\n",
"def score(TD: Prob, FG: Prob, extra: int) -> int: \n",
" \"\"\"Randomly simulate a score, given probabilities for TD and FG, and given the number of extra points.\"\"\"\n",
" return P(TD, 6 + extra) or P(FG / (1 - TD), 3)\n",
"\n",
"def P(p: Prob, points: int) -> int: \n",
" \"\"\"Return `points` with probability `p`, else 0.\"\"\"\n",
" return points if random.random() < p else 0"
]
},
{
"cell_type": "markdown",
"id": "cecd1023-957e-449b-8810-d34fcbe3ea33",
"metadata": {},
"source": [
"Let's play a random overtime game and see the scores of the two teams:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "3ca41256-ef10-40f9-9d39-c4e12a4b70b9",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(0, 3)"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"overtime()"
]
},
{
"cell_type": "markdown",
"id": "c78dd400-6ae7-410c-8494-7b74f9bb45aa",
"metadata": {},
"source": [
"# Code to Simulate a Million Games, and Draw Conclusions\n",
"\n",
"OK, but that's just one game. What if we play a million games?"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "b8c62d41-0bd3-4483-ba84-7a084b05510a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[((3, 0), 245539),\n",
" ((0, 3), 196710),\n",
" ((0, 6), 157459),\n",
" ((7, 0), 137498),\n",
" ((6, 0), 89649),\n",
" ((3, 6), 63006),\n",
" ((7, 6), 30297),\n",
" ((7, 8), 28557),\n",
" ((6, 3), 22473),\n",
" ((9, 3), 17667),\n",
" ((3, 9), 9921),\n",
" ((6, 7), 1206),\n",
" ((12, 6), 6),\n",
" ((9, 6), 5),\n",
" ((6, 12), 4),\n",
" ((6, 9), 3)]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Counter(overtime() for _ in range(1000_000)).most_common()"
]
},
{
"cell_type": "markdown",
"id": "3429fec7-2efe-4ee2-8309-acb8bed6b8a3",
"metadata": {},
"source": [
"That gives us the range of possible scores and the frequency of each one. Note:\n",
"- Field goals are more common than touchdowns, so the most common scores are 3-0 and 0-3.\n",
"- 3-0 is more common than 0-3, because 3-0 includes times when **A** scored first and also third (or later, but that's rarer).\n",
"- Why is 0-6 more common than 7-0? Because 0-6 includes times when **B** scored second, or fourth (or later).\n",
"- Note that the total of 7-0 (**A** scores first) and 6-0 (**A** scores third, or first and misses the kick) is more than the count for 0-6.\n",
"- Note that 3-6 is almost 3 times more common than 6-3. Either could result from 3 field goals, but 3-6 could also be **B** scoring a touchdown; 6-3 could never result from **A** scoring a touchdown.\n",
"- 6-9, 9-6, 12-6, and 6-12 are all rare scores, because they mean that *both* teams missed a kick.\n",
"\n",
"That's all interesting, but the question remains:\n",
"\n",
"## Who Has the Advantage, Team A or Team B?\n",
"\n",
"We can add up the games in which **A** wins:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "6b73b711-0073-4b40-893b-875a9ae6c8fa",
"metadata": {},
"outputs": [],
"source": [
"def win_probability(n=100_000, **kwds) -> float:\n",
" \"\"\"Probability that first team (team A) wins, in n simulations of overtime(**kwds).\"\"\"\n",
" scores = (overtime(**kwds) for _ in range(n))\n",
" return sum(A > B for A, B in scores) / n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "926afa2e-e60f-4641-bb18-b2f04c027f2f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.5438"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"win_probability()"
]
},
{
"cell_type": "markdown",
"id": "c7d4f929-04aa-484e-851d-2a83758d4948",
"metadata": {},
"source": [
"Using the given scoring percentages, my simulation says team **A** has about a 54% chance of winning. This supports Shanahan's decision. \n",
"\n",
"However, I don't have confidence that the probability parameter values I chose are reflective of reality, so let's explore a wider range of parameters: "
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "be360c09-bb94-4328-b439-4bcef5ff6ef3",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"from IPython.display import HTML\n",
" \n",
"def chart(TDs=(0.15, 0.20, 0.33), \n",
" FGs=(0.20, 0.25, 0.33), \n",
" gos=(0.05, 0.10, 0.20), \n",
" twos=(0, 0.48, 0.60),\n",
" n=100_000) -> HTML:\n",
" \"\"\"Create a chart of Win percentages for various parameter values.\"\"\"\n",
" data = [((win_probability(n=n, TD=TD, FG=FG, go=go)), TD, FG, go, two)\n",
" for TD in TDs for FG in FGs for go in gos for two in twos]\n",
" df = pd.DataFrame(data, columns=('Win', 'TD', 'FG', 'go', 'two')).sort_values('Win')\n",
" print(f'Team A win probability: min: {min(df.Win):.1%}, max: {max(df.Win):.1%}')\n",
" return HTML(df.to_html(index=False, formatters={'Win': '{:.1%}'.format}))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "e323e49e-84d7-43f6-99f2-8b9def6a4b0d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Team A win probability: min: 51.3%, max: 55.7%\n"
]
},
{
"data": {
"text/html": [
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>Win</th>\n",
" <th>TD</th>\n",
" <th>FG</th>\n",
" <th>go</th>\n",
" <th>two</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td>51.3%</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>51.4%</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>51.6%</td>\n",
" <td>0.33</td>\n",
" <td>0.25</td>\n",
" <td>0.20</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>51.7%</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>51.7%</td>\n",
" <td>0.33</td>\n",
" <td>0.25</td>\n",
" <td>0.20</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>51.9%</td>\n",
" <td>0.33</td>\n",
" <td>0.25</td>\n",
" <td>0.20</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>52.2%</td>\n",
" <td>0.33</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>52.6%</td>\n",
" <td>0.33</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>52.7%</td>\n",
" <td>0.33</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.2%</td>\n",
" <td>0.33</td>\n",
" <td>0.25</td>\n",
" <td>0.10</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.2%</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.10</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.2%</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.2%</td>\n",
" <td>0.20</td>\n",
" <td>0.25</td>\n",
" <td>0.20</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.3%</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.3%</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.3%</td>\n",
" <td>0.20</td>\n",
" <td>0.25</td>\n",
" <td>0.20</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.4%</td>\n",
" <td>0.33</td>\n",
" <td>0.25</td>\n",
" <td>0.10</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.4%</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.10</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.4%</td>\n",
" <td>0.20</td>\n",
" <td>0.25</td>\n",
" <td>0.20</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.4%</td>\n",
" <td>0.15</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.5%</td>\n",
" <td>0.33</td>\n",
" <td>0.25</td>\n",
" <td>0.10</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.5%</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.10</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.5%</td>\n",
" <td>0.15</td>\n",
" <td>0.25</td>\n",
" <td>0.20</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.7%</td>\n",
" <td>0.15</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.7%</td>\n",
" <td>0.33</td>\n",
" <td>0.33</td>\n",
" <td>0.10</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.7%</td>\n",
" <td>0.15</td>\n",
" <td>0.25</td>\n",
" <td>0.20</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.7%</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.05</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.8%</td>\n",
" <td>0.15</td>\n",
" <td>0.25</td>\n",
" <td>0.20</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.8%</td>\n",
" <td>0.15</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.9%</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.05</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53.9%</td>\n",
" <td>0.33</td>\n",
" <td>0.33</td>\n",
" <td>0.10</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.0%</td>\n",
" <td>0.33</td>\n",
" <td>0.25</td>\n",
" <td>0.05</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.0%</td>\n",
" <td>0.20</td>\n",
" <td>0.25</td>\n",
" <td>0.10</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.0%</td>\n",
" <td>0.20</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.0%</td>\n",
" <td>0.20</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.1%</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.10</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.1%</td>\n",
" <td>0.33</td>\n",
" <td>0.33</td>\n",
" <td>0.10</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.1%</td>\n",
" <td>0.15</td>\n",
" <td>0.20</td>\n",
" <td>0.10</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.1%</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.10</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.1%</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.05</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.1%</td>\n",
" <td>0.20</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.2%</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.10</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.2%</td>\n",
" <td>0.33</td>\n",
" <td>0.25</td>\n",
" <td>0.05</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.2%</td>\n",
" <td>0.15</td>\n",
" <td>0.20</td>\n",
" <td>0.10</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.2%</td>\n",
" <td>0.15</td>\n",
" <td>0.20</td>\n",
" <td>0.10</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.3%</td>\n",
" <td>0.15</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.3%</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.05</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.3%</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.05</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.3%</td>\n",
" <td>0.33</td>\n",
" <td>0.25</td>\n",
" <td>0.05</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.4%</td>\n",
" <td>0.20</td>\n",
" <td>0.25</td>\n",
" <td>0.10</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.4%</td>\n",
" <td>0.15</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.5%</td>\n",
" <td>0.20</td>\n",
" <td>0.25</td>\n",
" <td>0.10</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.5%</td>\n",
" <td>0.15</td>\n",
" <td>0.25</td>\n",
" <td>0.10</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.5%</td>\n",
" <td>0.20</td>\n",
" <td>0.25</td>\n",
" <td>0.05</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.5%</td>\n",
" <td>0.15</td>\n",
" <td>0.20</td>\n",
" <td>0.05</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.6%</td>\n",
" <td>0.15</td>\n",
" <td>0.20</td>\n",
" <td>0.05</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.6%</td>\n",
" <td>0.15</td>\n",
" <td>0.20</td>\n",
" <td>0.05</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.6%</td>\n",
" <td>0.20</td>\n",
" <td>0.20</td>\n",
" <td>0.05</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.7%</td>\n",
" <td>0.33</td>\n",
" <td>0.33</td>\n",
" <td>0.05</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.7%</td>\n",
" <td>0.15</td>\n",
" <td>0.25</td>\n",
" <td>0.10</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.7%</td>\n",
" <td>0.33</td>\n",
" <td>0.33</td>\n",
" <td>0.05</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.7%</td>\n",
" <td>0.15</td>\n",
" <td>0.33</td>\n",
" <td>0.20</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.8%</td>\n",
" <td>0.15</td>\n",
" <td>0.25</td>\n",
" <td>0.10</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.8%</td>\n",
" <td>0.15</td>\n",
" <td>0.25</td>\n",
" <td>0.05</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.8%</td>\n",
" <td>0.33</td>\n",
" <td>0.33</td>\n",
" <td>0.05</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.8%</td>\n",
" <td>0.20</td>\n",
" <td>0.25</td>\n",
" <td>0.05</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54.9%</td>\n",
" <td>0.15</td>\n",
" <td>0.25</td>\n",
" <td>0.05</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.0%</td>\n",
" <td>0.15</td>\n",
" <td>0.25</td>\n",
" <td>0.05</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.0%</td>\n",
" <td>0.20</td>\n",
" <td>0.33</td>\n",
" <td>0.10</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.0%</td>\n",
" <td>0.20</td>\n",
" <td>0.33</td>\n",
" <td>0.10</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.1%</td>\n",
" <td>0.20</td>\n",
" <td>0.25</td>\n",
" <td>0.05</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.1%</td>\n",
" <td>0.20</td>\n",
" <td>0.33</td>\n",
" <td>0.10</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.2%</td>\n",
" <td>0.20</td>\n",
" <td>0.33</td>\n",
" <td>0.05</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.2%</td>\n",
" <td>0.15</td>\n",
" <td>0.33</td>\n",
" <td>0.10</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.3%</td>\n",
" <td>0.15</td>\n",
" <td>0.33</td>\n",
" <td>0.10</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.3%</td>\n",
" <td>0.20</td>\n",
" <td>0.33</td>\n",
" <td>0.05</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.3%</td>\n",
" <td>0.15</td>\n",
" <td>0.33</td>\n",
" <td>0.10</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.4%</td>\n",
" <td>0.15</td>\n",
" <td>0.33</td>\n",
" <td>0.05</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.4%</td>\n",
" <td>0.20</td>\n",
" <td>0.33</td>\n",
" <td>0.05</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.4%</td>\n",
" <td>0.15</td>\n",
" <td>0.33</td>\n",
" <td>0.05</td>\n",
" <td>0.60</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55.7%</td>\n",
" <td>0.15</td>\n",
" <td>0.33</td>\n",
" <td>0.05</td>\n",
" <td>0.48</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chart()"
]
},
{
"cell_type": "markdown",
"id": "5773d2a1-642e-4a28-bfe9-b63e37aab2a2",
"metadata": {},
"source": [
"Now I feel more confident that across a wide range of parameter values, **A** always has the advantage.\n",
"\n",
"Another question still remains:\n",
"\n",
"## What Are the Best Strategies for Extra Points?\n",
"\n",
"Earlier I claimed that **A** should go for 1 and **B** for 2. That gives us about a 54% win probability for **A**:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "95f231d1-b7d4-4387-8cbf-4ae5cb3f7cdb",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.54277"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"win_probability(A_extra=1, B_extra=2)"
]
},
{
"cell_type": "markdown",
"id": "931acdc1-753a-4b7f-ae68-42c648eefef2",
"metadata": {},
"source": [
"We can see that if **A** goes for 2, they will do worse:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "3a374721-3e4e-4185-90f5-4e27cc0de458",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.53674"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"win_probability(A_extra=2, B_extra=2)"
]
},
{
"cell_type": "markdown",
"id": "009a1a1d-8c58-45ab-8ee2-b597915b523a",
"metadata": {},
"source": [
"We can also see that if **B** goes for 1, they will do worse (i.e., **A** will do better):"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "8a24b181-16d3-4c30-84af-25ceb5c55929",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.55175"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"win_probability(A_extra=1, B_extra=1)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.8.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
notebooks = {
'Recent (2022)': [], # Gets updated automatically
'Recent (20222024)': [], # Gets updated automatically
'Programming Examples': [
("AlphaCode Automated Programming", 2022, 'AlphaCode.ipynb', "Analysis of AlphaCode's automated solution to a coding problem"),
@ -138,7 +138,7 @@ def find_recent(notebooks) -> None:
recent = next(key for key in notebooks if key.startswith('Recent'))
for category in notebooks:
for line in notebooks[category]:
if line[1] in {2022}:
if line[1] in {2022, 2023, 2024}:
notebooks[recent].append(line)
def format_category(category) -> str: