Streamline previous content
- run grammarly on all notebooks - add section on short-circuiting in chapter 03
This commit is contained in:
parent
6bebe70e24
commit
dbc3a67af4
11 changed files with 1566 additions and 1377 deletions
|
|
@ -54,7 +54,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Q2**: Solving a problem with a **recursion** is not only popular in computer science and math. Name some examples from the fields of business or economics where problems are also solved in a **backwards** fashion!"
|
||||
"**Q2**: Solving a problem by **recursion** is not only popular in computer science and math. Name some examples from the fields of business or economics where problems are also solved in a **backward** fashion!"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -68,7 +68,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Q3**: Explain what **duck typing** means! Why can it cause problems? Why it is [not a bug but a feature](https://www.urbandictionary.com/define.php?term=It%27s%20not%20a%20bug%2C%20it%27s%20a%20feature)?"
|
||||
"**Q3**: Explain what **duck typing** means! Why can it cause problems? Why is it [not a bug but a feature](https://www.urbandictionary.com/define.php?term=It%27s%20not%20a%20bug%2C%20it%27s%20a%20feature)?"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -208,7 +208,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Q12**: Whereas a **recursion** may accidently result in a **never ending** program, `while`-loops and `for`-loops are guaranteed to **terminate**."
|
||||
"**Q12**: Whereas a **recursion** may accidentally result in a **never-ending** program, `while`-loops and `for`-loops are guaranteed to **terminate**."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -275,7 +275,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"A popular example for a problem that is solved with a recursion art the **[Towers of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi)**.\n",
|
||||
"A popular example of a problem that is solved by recursion art the **[Towers of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi)**.\n",
|
||||
"\n",
|
||||
"In its basic version, a tower consisting of, for example, four disks with increasing radii, is placed on the left-most of **three** adjacent spots. In the following, we refer to the number of disks as $n$, so here $n = 4$.\n",
|
||||
"\n",
|
||||
|
|
@ -304,9 +304,9 @@
|
|||
"source": [
|
||||
"Watch the following video by [MIT](https://www.mit.edu/)'s professor [Richard Larson](https://idss.mit.edu/staff/richard-larson/) for a comprehensive introduction.\n",
|
||||
"\n",
|
||||
"The [MIT Blossoms Initative](https://blossoms.mit.edu/) is primarily aimed at high school students and does not have any prerequisites.\n",
|
||||
"The [MIT Blossoms Initiative](https://blossoms.mit.edu/) is primarily aimed at high school students and does not have any prerequisites.\n",
|
||||
"\n",
|
||||
"The video consists of three segments the last of which is *not* necessary to have watched in order to solve the tasks below. So, watch the video until 37:55."
|
||||
"The video consists of three segments, the last of which is *not* necessary to have watched to solve the tasks below. So, watch the video until 37:55."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -393,7 +393,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"As most likely the first couple of tries will result in *semantic* errors, it is advisable to have some sort of **visualization tool** for the progam's output: For example, an online version of the game can be found **[here](https://www.mathsisfun.com/games/towerofhanoi.html)**."
|
||||
"As most likely the first couple of tries will result in *semantic* errors, it is advisable to have some sort of **visualization tool** for the program's output: For example, an online version of the game can be found **[here](https://www.mathsisfun.com/games/towerofhanoi.html)**."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -402,7 +402,7 @@
|
|||
"source": [
|
||||
"Let's first **generalize** the mathematical relationship from above.\n",
|
||||
"\n",
|
||||
"While the first number of $Sol(\\cdot)$ is the number of `disks` $n$, the second and third \"numbers\" are actually the **labels** for the three spots. Instead of spots `1`, `2`, and `3` we could also call them `\"left\"`, `\"center\"`, and `\"right\"` in our Python implementation. When \"passed\" to the $Sol(\\cdot)$ \"function\" they take on the role of an `origin` (= $o$) and `destination` (= $d$) pair.\n",
|
||||
"While the first number of $Sol(\\cdot)$ is the number of `disks` $n$, the second and third \"numbers\" are the **labels** for the three spots. Instead of spots `1`, `2`, and `3`, we could also call them `\"left\"`, `\"center\"`, and `\"right\"` in our Python implementation. When \"passed\" to the $Sol(\\cdot)$ \"function\" they take on the role of an `origin` (= $o$) and `destination` (= $d$) pair.\n",
|
||||
"\n",
|
||||
"So, the expression $Sol(4, 1, 3)$ is the same as $Sol(4, \\text{\"left\"}, \\text{\"right\"})$ and describes the problem of moving a tower consisting of $n = 4$ disks from `origin` `1` / `\"left\"` to `destination` `3` / `right`. As we have seen in the video, we need some `intermediate` (= $i$) spot."
|
||||
]
|
||||
|
|
@ -420,9 +420,9 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In words, this means that in order to move a tower consisting of $n$ disks from an `origin` $o$ to a `destination` $d$, three steps must be executed:\n",
|
||||
"In words, this means that to move a tower consisting of $n$ disks from an `origin` $o$ to a `destination` $d$, three steps must be executed:\n",
|
||||
"\n",
|
||||
"1. Move the top most $n - 1$ disks of the tower temporarily from $o$ to $i$ (= sub-problem 1)\n",
|
||||
"1. Move the topmost $n - 1$ disks of the tower temporarily from $o$ to $i$ (= sub-problem 1)\n",
|
||||
"2. Move the remaining and largest disk from $o$ to $d$\n",
|
||||
"3. Move the the $n - 1$ disks from the temporary spot $i$ to $d$ (= sub-problem 2)\n",
|
||||
"\n",
|
||||
|
|
@ -435,9 +435,9 @@
|
|||
"source": [
|
||||
"$Sol(\\cdot)$ can be written in Python as a function `sol()` that takes three arguments `disks`, `origin`, and `destination` that mirror $n$, $o$, and $d$.\n",
|
||||
"\n",
|
||||
"Assume that all arguments to `sol()` will be `int` objects!\n",
|
||||
"Assume that all arguments to `sol()` are `int` objects!\n",
|
||||
"\n",
|
||||
"Once completed, `sol()` should print out all the moves in the correct order. With **printing a move**, we simply mean a line like \"1 -> 3\", short for \"Move the top-most disk from spot 1 to spot 3\".\n",
|
||||
"Once completed, `sol()` should print out all the moves in the correct order. With **printing a move**, we mean a line like \"1 -> 3\", short for \"Move the top-most disk from spot 1 to spot 3\".\n",
|
||||
"\n",
|
||||
"Write your answers to **Q15.5** to **Q15.7** into the subsequent code cell and finalize `sol()`! No need to write a docstring or validate the input here."
|
||||
]
|
||||
|
|
@ -550,9 +550,9 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The previous `sol()` implementation does the job but the conditional statement needed in unnecessarily tedious. \n",
|
||||
"The previous `sol()` implementation does the job, but the conditional statement needed in unnecessarily tedious. \n",
|
||||
"\n",
|
||||
"Let's create a more concise `hanoi()` function that in addition to a positional `disks` argument takes three keyword-only arguments `origin`, `intermediate`, and `destination` with default values `\"left\"`, `\"center\"`, and `\"right\"`.\n",
|
||||
"Let's create a more concise `hanoi()` function that, in addition to a positional `disks` argument, takes three keyword-only arguments `origin`, `intermediate`, and `destination` with default values `\"left\"`, `\"center\"`, and `\"right\"`.\n",
|
||||
"\n",
|
||||
"Write your answers to **Q15.9** and **Q15.10** into the subsequent code cell and finalize `hanoi()`! No need to write a docstring or validate the input here."
|
||||
]
|
||||
|
|
@ -588,7 +588,7 @@
|
|||
"\n",
|
||||
"Figure out how the arguments are passed on in the two recursive `hanoi()` calls!\n",
|
||||
"\n",
|
||||
"Also, write a `print()` statement analogous to the one in `sol()` in between the two recursive function calls. Is it ok to just copy and paste it?"
|
||||
"Also, write a `print()` statement analogous to the one in `sol()` in between the two recursive function calls. Is it ok to copy and paste it?"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -638,7 +638,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We could of course also use **numeric labels** for the three steps like so."
|
||||
"We could, of course, also use **numeric labels** for the three steps like so."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -661,13 +661,13 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's say, we did not know about the **analytical formula** for the number of **minimal moves** given $n$.\n",
|
||||
"Let's say we did not know about the **analytical formula** for the number of **minimal moves** given $n$.\n",
|
||||
"\n",
|
||||
"In such cases, we could modify a recursive function to return a count value to be passed up the recursion tree.\n",
|
||||
"\n",
|
||||
"In fact, this is similar to what we do in the recursive versions of `factorial()` and `fibonacci()` in [Chapter 4](https://github.com/webartifex/intro-to-python/blob/master/04_iteration.ipynb) where we pass up an intermediate result.\n",
|
||||
"This is similar to what we do in the recursive versions of `factorial()` and `fibonacci()` in [Chapter 4](https://github.com/webartifex/intro-to-python/blob/master/04_iteration.ipynb), where we pass up an intermediate result.\n",
|
||||
"\n",
|
||||
"Let's create a `hanoi_moves()` function that follows the same internal logic as `hanoi()` but instead of printing out the moves returns the number of steps done so far in the recursion.\n",
|
||||
"Let's create a `hanoi_moves()` function that follows the same internal logic as `hanoi()`, but, instead of printing out the moves, returns the number of steps done so far in the recursion.\n",
|
||||
"\n",
|
||||
"Write your answers to **Q15.12** to **Q15.14** into the subsequent code cell and finalize `hanoi_moves()`! No need to write a docstring or validate the input here."
|
||||
]
|
||||
|
|
@ -742,7 +742,7 @@
|
|||
"source": [
|
||||
"Observe how quickly the `hanoi_moves()` function slows down for increasing `disks` arguments.\n",
|
||||
"\n",
|
||||
"With `disks` in the range from `24` through `26` the computation time roughly doubles for each increase of `disks` by 1.\n",
|
||||
"With `disks` in the range from `24` through `26`, the computation time roughly doubles for each increase of `disks` by 1.\n",
|
||||
"\n",
|
||||
"**Q15.16**: Execute the code cells below and see for yourself!"
|
||||
]
|
||||
|
|
@ -788,7 +788,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The above `hanoi()` prints the optimal solution's moves in the correct order but fails to label each move with an order number. This can be build in by passing on one more argument `offset` down the recursion tree. As the logic gets a bit \"involved\", `hanoi_ordered()` below is almost finished.\n",
|
||||
"The above `hanoi()` prints the optimal solution's moves in the correct order but fails to label each move with an order number. This can be built in by passing on one more argument `offset` down the recursion tree. As the logic gets a bit \"involved,\" `hanoi_ordered()` below is almost finished.\n",
|
||||
"\n",
|
||||
"Write your answers to **Q15.17** and **Q15.18** into the subsequent code cell and finalize `hanoi_ordered()`! No need to write a docstring or validate the input here."
|
||||
]
|
||||
|
|
@ -879,7 +879,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Lastly, it is to be mentioned that for problem instances with a small `disks` argument it is easier to collect all the moves first in a list and then add the order number with the [enumerate()](https://docs.python.org/3/library/functions.html#enumerate) built-in."
|
||||
"Lastly, it is to be mentioned that for problem instances with a small `disks` argument, it is easier to collect all the moves first in a list and then add the order number with the [enumerate()](https://docs.python.org/3/library/functions.html#enumerate) built-in."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue