diff --git a/README.md b/README.md
index 6da08439ffab57bd6d434b04b62698cb9be15a4e..3c88171bb281ec2e5eead6689693d5e0e7d91a37 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,13 @@
 Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr)
 
 <div style="text-align: center;">
-    <img src="figures/logo-ecl.png" style="width:20%; display:inline-block; vertical-align:middle;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-    <img src="figures/logo-emlyon.png" style="width:20%; display:inline-block; vertical-align:middle;">
+    <img src="figures/logo-ecl.png" width="20%" style="width:20%; display:inline-block; vertical-align:middle;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+    <img src="figures/logo-emlyon.png" width="20%" style="width:20%; display:inline-block; vertical-align:middle;">
 </div>
 
 ## Course description
 
-- Basis of algorithms (sorting, search) and data structure (arrays, lists)
+- Basics of algorithms and data structure
 - Justification of the choice of data structures
 - Calculate the complexity of an algorithm
 - Optimize algorithms
@@ -18,13 +18,11 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr)
 
 ## Course material
 
-- [lectures](https://gitlab.ec-lyon.fr/rvuillem/algo-bsc/-/tree/main/lectures): lectures presented in class
+- [lectures](https://gitlab.ec-lyon.fr/rvuillem/algo-bsc/-/tree/main/lectures): slides and code presented in class
 
 - [notebooks](https://gitlab.ec-lyon.fr/rvuillem/algo-bsc/-/tree/main/notebooks): notebook of the lectures with editable code
 
-- [📝 exercises](https://gitlab.ec-lyon.fr/rvuillem/algo-bsc/-/tree/main/exercises): lab exercices
-
-- [solutions](https://gitlab.ec-lyon.fr/rvuillem/algo-bsc/-/tree/main/solutions): solutions of lab exercises
+- [📝 exercises](https://gitlab.ec-lyon.fr/rvuillem/algo-bsc/-/tree/main/exercises): lab exercices and [solutions](https://gitlab.ec-lyon.fr/rvuillem/algo-bsc/-/tree/main/solutions)
 
 - [📖 books](https://gitlab.ec-lyon.fr/rvuillem/algo-bsc/-/tree/main/books): books and ressources to prepare the lecture & learn more
 
@@ -34,7 +32,7 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr)
 ### [Lecture 1 - **Data structures and complexity**](lectures/01-data-structures-complexity%20slides.pdf)
 
 - Introduction to data structures
-- Asymptotic analysis (Big O notation)
+- Complexity calculation and analysis (Big O notation)
 - Data structures
 - Trade-offs between time/space complexity and different data structures
 - Empirical calculation of complexity
@@ -90,8 +88,6 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr)
 
 </details>
 
-
-
 ### Lab 3 - **Stacks and queues** 
 
 ---
diff --git a/assignments/README 2.md b/assignments/README 2.md
new file mode 100644
index 0000000000000000000000000000000000000000..6bf7200d1fe3d55885149d851272a2d9466f88eb
--- /dev/null
+++ b/assignments/README 2.md	
@@ -0,0 +1,11 @@
+# UE5 Fundamentals of Algorithms
+### Bachelor of Science in Data Science for Responsible Business
+
+Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr)
+
+<div style="text-align: center;">
+    <img src="../figures/logo-ecl.png" width="20%" style="width:20%; display:inline-block; vertical-align:middle;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+    <img src="../figures/logo-emlyon.png" width="20%" style="width:20%; display:inline-block; vertical-align:middle;">
+</div>
+
+## Assignments
diff --git a/assignments/assignment-01.ipynb b/assignments/assignment-01.ipynb
deleted file mode 100644
index e0bcfee61ad92f2217316672abca25644913a29f..0000000000000000000000000000000000000000
--- a/assignments/assignment-01.ipynb
+++ /dev/null
@@ -1,365 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "a016336c",
-   "metadata": {},
-   "source": [
-    "NAME:"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "db477b79",
-   "metadata": {},
-   "source": [
-    "<center>\n",
-    "    <h3>ASSIGNMENT#1 (Algorithms) - Nov. 27, 2023</h3>\n",
-    "</center>\n",
-    "\n",
-    "Due date: **December 8th, 2023, 5pm** (no extension will be allowed).\n",
-    "\n",
-    "Submit your solution by email: romain.vuillemot@ec-lyon.fr\n",
-    "\n",
-    "You may work as a group (max 2) but all members are required to submit their solution and indicate their collaborator (if any).\n",
-    "\n",
-    "## Goal of this assignment\n",
-    "\n",
-    "In this assignment we provide you with a dataset of characters from a movie. Your role will be to answer the questions below programmatically, using Pyhon. **Please note you need to answer with fully working python code embedded in this notebook as solution (no external modules or files can be included).** You may then replace the code below with your answer for each question:\n",
-    "\n",
-    "```python\n",
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()\n",
-    "```\n",
-    "\n",
-    "## Grading\n",
-    "\n",
-    "- 20% for the results to the questions\n",
-    "- 60% for the code quality\n",
-    "- 20% for the notebook presentation\n",
-    "-  +10% bonus question\n",
-    "\n",
-    "## Getting started\n",
-    "\n",
-    "We provide you with a dataset containing movie characters. Each character is represented as a row, along with connections to other characters, based on the movie script. You will use those connections to create a graph-based data structure and answer the questions. \n",
-    "\n",
-    "To get you started with the dataset, we provide you with the code that loads it:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "cf409997-537f-4f89-a039-c2b3494972f2",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "data_file = 'users.csv'\n",
-    "\n",
-    "with open(data_file, 'r') as file:\n",
-    "    lines = file.readlines()\n",
-    "    data = [tuple(line.strip().split(',')) for line in lines[1:]]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "c48b6391-d858-4a35-b428-b99434ee2d57",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "The `data` variable contains the list of characters. You may look at the `users.csv` file to grasp the values of this variable. Here is a sample:\n",
-    "\n",
-    "```\n",
-    "[('Tony_Stark',\n",
-    "  '40',\n",
-    "  'Male',\n",
-    "  '1.85',\n",
-    "  'Steve_Rogers Natasha_Romanoff Bruce_Banner Thor_Odinson'),\n",
-    " ('Steve_Rogers',\n",
-    "  '98',\n",
-    "  'Male',\n",
-    "  '1.88',\n",
-    "  'Tony_Stark Natasha_Romanoff Sam_Wilson Bucky_Barnes'),\n",
-    "...\n",
-    "```"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "70e93e78-f4dd-435f-b0f7-d56d928d7051",
-   "metadata": {},
-   "source": [
-    "**Question 1 -** How many characters are there in the dataset?"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9022b450-6fa6-41d0-999e-e019917cda79",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "6474e3afbe1bbdb5b06ce64fc0534c4f",
-     "grade": false,
-     "grade_id": "cell-f45150625899eb53",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "0a1a4c6c-f95c-4dc3-8bb3-863d1048ae79",
-   "metadata": {},
-   "source": [
-    "**Question 2 -** Write a function that turns the `data` variable into a dictionnary data structure like the one below. You may then be able to plot it with the `plot_character_connections` function provided in the next cell:\n",
-    "\n",
-    "```\n",
-    "{'Tony_Stark': ['Steve_Rogers', 'Natasha_Romanoff', 'Bruce_Banner', 'Thor_Odinson'], 'Steve_Rogers': ['Tony_Stark', 'Natasha_Romanoff', 'Sam_Wilson', 'Bucky_Barnes'],\n",
-    "..\n",
-    "```"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "7139b3cf-1c00-43bb-bc1b-67b4a8e2a92d",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "65a8683bbae1730e7882a91135df6dfa",
-     "grade": false,
-     "grade_id": "cell-2b24cbad2d825c82",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "adjacency_list = {}\n",
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "fbbdd57e-6895-4d3c-b561-406d5e6668a9",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# please run the cells below the \"Utils\" section first\n",
-    "plot_character_connections(adjacency_list)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "4a62b350-2bc8-476d-b9c6-13a08d649bdc",
-   "metadata": {},
-   "source": [
-    "**Question 3 -**  Is there a character self-connected to her/himself?"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "232f3d2a-8300-40c1-a908-ebfa5e380ae1",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "12487a86c6f58024a3ebbe0d242b5d48",
-     "grade": false,
-     "grade_id": "cell-641c5f735f36d3f6",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "b79c97bc-e7d5-4ff4-bb1c-5bdf1e3abae2",
-   "metadata": {},
-   "source": [
-    "**Question 4 -** How many communities can you identify? We define a community as a sub-graph of connected people by a path (i.e. a connected component)."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "98186a3a-bd4c-4bf8-9ebd-2f350a83c856",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "dcfadd1483b4e91449dcd93f77e36868",
-     "grade": false,
-     "grade_id": "cell-7b6675c6e2784006",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "840a8875-2f71-4da9-bbe7-0f1aab5f612b",
-   "metadata": {},
-   "source": [
-    "**Question 5 -** Are connections mutual in the graph?"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "12d15b4d-cf98-45aa-994c-e41070b9ea3a",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "90802fd6bde9d5da3b4577c3d86f9774",
-     "grade": false,
-     "grade_id": "cell-8875e1c325dd6853",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5e1b0409-1dff-4d8b-a5d8-a1efa1c10125",
-   "metadata": {},
-   "source": [
-    "**Question 6 (BONUS) -**  Among the community of characters, is there a fully connected one? (i.e. where all characters are directly connected to the others)."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "d8a1900d-c15f-4ef4-83d8-1ecfbc8bfcf8",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "8a0cd9235224e442fb7dfe36544029cf",
-     "grade": false,
-     "grade_id": "cell-777cc851157e530d",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "00c753ed-0905-4132-b276-4b415ba31408",
-   "metadata": {},
-   "source": [
-    "## Utils"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "d9f71538-98b6-4730-adc1-7ca84aa3748e",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import networkx as nx\n",
-    "import matplotlib.pyplot as plt\n",
-    "\n",
-    "def plot_character_connections(adjacency_list):\n",
-    "    G = nx.DiGraph()\n",
-    "    for character, connections in adjacency_list.items():\n",
-    "        G.add_node(character)\n",
-    "        for connection in connections:\n",
-    "            G.add_edge(character, connection)\n",
-    "\n",
-    "    plt.figure(figsize=(12, 8))\n",
-    "    pos = nx.spring_layout(G, seed=42)\n",
-    "\n",
-    "    nx.draw(\n",
-    "        G,\n",
-    "        pos,\n",
-    "        with_labels=True,\n",
-    "        node_size=500,\n",
-    "        node_color='skyblue',\n",
-    "        font_weight='bold',\n",
-    "        font_size=10\n",
-    "    )\n",
-    "    plt.title('Movie characters')\n",
-    "    plt.show()"
-   ]
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/assignments/users.csv b/assignments/users.csv
deleted file mode 100644
index 72aef4326ad52e473b11f4aeab8603d617181f38..0000000000000000000000000000000000000000
--- a/assignments/users.csv
+++ /dev/null
@@ -1,18 +0,0 @@
-Name,Age,Gender,Height,Connections
-Tony_Stark,40,Male,1.85,Steve_Rogers Natasha_Romanoff Bruce_Banner Thor_Odinson
-Steve_Rogers,98,Male,1.88,Tony_Stark Natasha_Romanoff Sam_Wilson Bucky_Barnes
-Natasha_Romanoff,35,Female,1.65,Clint_Barton Bruce_Banner Tony_Stark Steve_Rogers
-Bruce_Banner,42,Male,1.75,Tony_Stark Natasha_Romanoff Thor_Odinson
-Thor_Odinson,1500,Male,1.98,Tony_Stark Bruce_Banner Loki Odin
-Clint_Barton,40,Male,1.83,Natasha_Romanoff Laura_Barton
-Sam_Wilson,35,Male,1.83,Steve_Rogers Bucky_Barnes Sergent_Rhodes
-Bucky_Barnes,106,Male,1.83,Steve_Rogers Sam_Wilson
-Thanos,Unknown,Male,2.13,Gamora Nebula Loki
-Loki,Unknown,Male,1.82,Thanos Thor_Odinson
-Gamora,Unknown,Female,1.83,Thanos Nebula
-Nebula,Unknown,Female,1.78,Thanos Gamora
-Odin,5000,Male,2.05,Thor_Odinson Loki
-Sergent_Rhodes,50,Male,1.85,Tony_Stark Sam_Wilson
-Shuri,18,Female,1.68,T_Challa Okoye
-T_Challa,45,Male,1.83,Shuri Okoye
-Okoye,38,Female,1.75,Shuri T_Challa
diff --git a/exercises/02-recursion-exercises.ipynb b/exercises/02-recursion-exercises.ipynb
deleted file mode 100644
index 5bb9efa8ff4b32d695f18ff8abe9acbf7cd0dce3..0000000000000000000000000000000000000000
--- a/exercises/02-recursion-exercises.ipynb
+++ /dev/null
@@ -1,1110 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "aed5654c",
-   "metadata": {},
-   "source": [
-    "NAME:"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a4e4fad3",
-   "metadata": {
-    "slideshow": {
-     "slide_type": "slide"
-    }
-   },
-   "source": [
-    "# Recursion"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a8adef9b",
-   "metadata": {
-    "slideshow": {
-     "slide_type": "skip"
-    }
-   },
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0dfe1da3-b50b-49c0-aaff-483616e13863",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "list_complexities = [\"O(1)\", \"O(log(n))\", \"O(n)\", \"O(n^2)\", \"O(nlog(n))\", \"O(n^3)\", \"O(2^n)\", \"O(n!)\", \"O(n^n)\"]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "568202fd",
-   "metadata": {
-    "slideshow": {
-     "slide_type": "subslide"
-    }
-   },
-   "source": [
-    "### Exercise 0: Find the maximum value in a list (iterative)\n",
-    "\n",
-    "Write a function `find_maximum_iterative` that takes a list of numbers as input and returns the maximum value in the list. For this question, you are  not allowed to use built-in functions like `max()`."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "431fe8c1-91d1-40f3-a7a4-f4a3770a4a01",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "8b23d599da9ca2bdba48b9bcdd6e1165",
-     "grade": false,
-     "grade_id": "find_maximum_iterative",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def find_maximum_iterative(L):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f6baae3c-3660-4add-ab4b-48016cba3030",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "find_maximum_iterative([1, 3, 5, 7, 9])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "e68b3e9a-418f-4950-9f27-18bb0fe90794",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "9cb3441fa27dd28ce74e368375de8080",
-     "grade": true,
-     "grade_id": "correct_find_maximum_iterative",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert find_maximum_iterative([1, 3, 5, 7, 9]) == 9\n",
-    "assert find_maximum_iterative([-1, -5, -3]) == -1\n",
-    "assert find_maximum_iterative([42]) == 42\n",
-    "assert find_maximum_iterative([4, 8, 8, 2, 7]) == 8\n",
-    "assert find_maximum_iterative([-10, -5, -8, -2, -7]) == -2"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "612dc873-419b-42c5-be36-0accd03ffa79",
-   "metadata": {},
-   "source": [
-    "### Exercise 1: Find the maximum value in a list (recursive)\n",
-    "\n",
-    "Write a recursive version of the previous function; you may use the `max()` function for the recursive call."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "07668fd8",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "fcd4348ffdf05fa800f15e7dba033d8e",
-     "grade": false,
-     "grade_id": "find_maximum_recursive",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def find_maximum_recursive(L):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f9784710-4b2b-434c-bc47-da46fa410749",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "find_maximum_recursive([1, 3, 5, 7, 9])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9b0161f8-0539-4e5e-921c-1886e61c0783",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "1aae7ba6a868f7afd015deedcdf48aa4",
-     "grade": true,
-     "grade_id": "correct_find_maximum_recursive",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert find_maximum_iterative([-10, -5, -8, -2, -7]) == find_maximum_recursive([-10, -5, -8, -2, -7])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "005efd41-baa1-4505-b80e-3644d61ea094",
-   "metadata": {},
-   "source": [
-    "### Exercise 2: Sum of digits"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "de424156-0b9b-41d0-8e38-ce335f35cec0",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "3872f4f922847e273bc5a45cd425c458",
-     "grade": false,
-     "grade_id": "sum_of_digits",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sum_of_digits(n):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "cec0caca-cb2c-4e4d-b004-27b3cf2ff611",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "sum_of_digits(10)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "bf276ca2-48ed-4e87-80f2-776f54b7062b",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "feb0a5b734f6734920bfec23da86992b",
-     "grade": true,
-     "grade_id": "correct_sum_of_digits",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert sum_of_digits(10) == sum_of_digits(100000)\n",
-    "assert sum_of_digits(0) == 0\n",
-    "assert sum_of_digits(123) == 6"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e2de630a-f9bd-4d45-959b-430e34cc9044",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "### Exercise 3: Calculate the power"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "abca03a0-7bcd-4ee6-b109-ff2f2da52bb6",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "c8c385784b4dd53e96c693511e7a2e80",
-     "grade": false,
-     "grade_id": "power",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def power(base, exponent):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "abddd3b1-f75f-4cb6-a09e-54eed489c5b0",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "power(2, 10)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "8a6605fe-4f6f-45de-84a3-7601e2e2e6f6",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "1deb1e7cdc63de1900c5375bf6debf2a",
-     "grade": true,
-     "grade_id": "correct_power",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert power(2, 10) == 1024\n",
-    "assert power(2, 0) == 1\n",
-    "assert power(5, 3) == 125"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "715100d3-fc21-49b9-a66d-b5243b4a279d",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "### Exercise 4: Reverse a string\n",
-    "\n",
-    "In a recursive way:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ddc9826a-0863-4777-a08d-81b66652b5a5",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "762d91a747e5399677a26e44c5d8a041",
-     "grade": false,
-     "grade_id": "reverse_string",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def reverse_string(s):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "13acad7e-d03c-4ea6-ad86-baf02e0910eb",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "reverse_string(\"Romain\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "453c8e04-6cd9-4581-a206-dd479b6115cd",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "d42cbfb82df47fb4eb82e1530fa8f3cb",
-     "grade": true,
-     "grade_id": "correct_reverse_string",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert reverse_string(\"\") == \"\"\n",
-    "assert reverse_string(\"AA\") == \"AA\"\n",
-    "assert reverse_string(\"ABC\") == \"CBA\""
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "c1587148-f816-4af2-8f3a-6d8a8480d54d",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "In an iterative way:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "159b6d78-03ae-4cf8-8545-e822b7160b32",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "d95c7211470341d4c1e960c2b506d676",
-     "grade": false,
-     "grade_id": "cell-ead02fa889911e42",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def iterative_reverse_string(s):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0dcdbd99-5f57-4d1c-bc31-8f8afc617d0e",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "iterative_reverse_string(\"Romain\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "43e10b0c",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "assert iterative_reverse_string(\"Romain\") == reverse_string(\"Romain\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5ab8f3c9-ddee-45ab-a013-fdd67d9853e0",
-   "metadata": {},
-   "source": [
-    "### Example 5: convert an interative suite into a recursive tail function\n",
-    "\n",
-    "_A recursive tail function is a function where the last operation is the recursive call._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "219add7f",
-   "metadata": {
-    "slideshow": {
-     "slide_type": "subslide"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sequence(n):\n",
-    "    u = 1\n",
-    "    while n > 0:\n",
-    "        u = 2 * u + 1\n",
-    "        n -= 1\n",
-    "    return u"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0787df24-8234-4286-b910-5f9e456dd279",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "print(\"The result is {}\".format(sequence(3)))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9c17cf1b-6d05-4589-af2b-c05cfcc33202",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "2137e4ccdef7bccaa7b7ed6b52f305a8",
-     "grade": false,
-     "grade_id": "sequence_recursive_tail",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sequence_recursive_tail(n):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "43507c43-de61-414d-b389-c0a771ad9e0c",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "print(\"The result is still {}\".format(sequence_recursive_tail(3)))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "dd923b7c-0cab-4678-8dc3-aad2ab9b25f9",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "c465dc72b44f305c781da5cf50e4c934",
-     "grade": true,
-     "grade_id": "correct_sequence_recursive_non_tail",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "slideshow": {
-     "slide_type": "slide"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert sequence_recursive_tail(3) == 15"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "3c28b36a",
-   "metadata": {
-    "slideshow": {
-     "slide_type": "subslide"
-    }
-   },
-   "source": [
-    "### Example 6: check if a word is a palindrom\n",
-    "\n",
-    "Check if a word can be read backwards."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "51bb3d08",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "a11e9594f7e72af63464586312e41230",
-     "grade": false,
-     "grade_id": "annagram_rec",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def palindrom_rec(word):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0c279628-9b96-4687-8e20-a954ab646e0f",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "palindrom_rec(\"laval\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "cf6fa61a-7c6f-4a32-96c2-b9fd50deacc6",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "ef3b3eadc729e907ea2d4da9b32fed0c",
-     "grade": true,
-     "grade_id": "correct_annagram_rec",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert palindrom_rec(\"\")\n",
-    "assert palindrom_rec(\"AA\")\n",
-    "assert not palindrom_rec(\"ABC\")\n",
-    "assert palindrom_rec(\"ABA\")\n",
-    "assert palindrom_rec(\"LAVAL\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "798c2875-7940-488a-8458-ad08f6a71c70",
-   "metadata": {},
-   "source": [
-    "### Example 7: Calculate GCD\n",
-    "\n",
-    "_Here is the iterative way, write the recursive equivalent._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "48c65c83-be0c-41c4-8c04-1d29ac4415cb",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def iterative_gcd(a, b):\n",
-    "    while b:\n",
-    "        a, b = b, a % b\n",
-    "    return a"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "bf6e1a76",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "45353cb0fdd92b57e6f6f1739ed430b3",
-     "grade": false,
-     "grade_id": "recursive_gcd",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def recursive_gcd(a, b):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4f1feace",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "recursive_gcd(10, 2)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "e6ff1765-ff4b-49a5-80d3-684d2627e961",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "ed3ae90c2a4be5ff93a5d68b688f0f96",
-     "grade": true,
-     "grade_id": "correct_recursive_gcd",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert iterative_gcd(10, 2) == recursive_gcd(10, 2)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "d8b05edf-9536-4fc1-bfcc-ddbbeee426fc",
-   "metadata": {},
-   "source": [
-    "### Example 8: Check if a list of numbers is sorted"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1661dfb5-88f2-411f-8fe2-63bbaa29ce72",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "862e6666538916866c4f2ee16d767102",
-     "grade": false,
-     "grade_id": "calculate_average_recursive",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def is_sorted(L):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0c5c72c6-3237-4f98-ab96-50a1838b833f",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "is_sorted([1, 2, 3, 4, 5])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9f18b6b7-d980-4a72-a2a8-3aa201003d21",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "c433fabbd5212a4d85564afad33f568e",
-     "grade": true,
-     "grade_id": "correct_calculate_average_recursive",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert is_sorted([2, 3])\n",
-    "assert is_sorted([])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "79eef392-1d3d-46c0-aeee-ac805686e6f1",
-   "metadata": {},
-   "source": [
-    "### Example 9: Check for prime number in a recursive function"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ac374a08-11c9-47e6-ba11-419549911266",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "58fec5e697f40d4e1934bdce3ae87647",
-     "grade": false,
-     "grade_id": "is_prime_recursive",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def is_prime_recursive(n, divisor=2):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "996fc91f",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "is_prime_recursive(3)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5be1051c-3b60-4810-b855-6f8575ad6380",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "f571ff3e3a5bc53ffbc828b255bfb6cb",
-     "grade": true,
-     "grade_id": "correct_is_prime_recursive",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert is_prime_recursive(3) "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5423682d-c31f-4a8d-9a0f-6812de7b1ae3",
-   "metadata": {},
-   "source": [
-    "### Example 10: Count occurrences of a given element in a list"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "cfeb0ad0-ed82-499e-9af3-64923291a0e7",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "dc82bb9d69427f625dd25265e766086e",
-     "grade": false,
-     "grade_id": "count_occurrences",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def count_occurrences(L, target, index=0):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "49daec07-00b3-412e-ad44-5bafadbd9f36",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "count_occurrences([1, 2, 3, 4, 2, 2, 5, 6, 2], 2)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "14a2eb85-1126-4506-93bb-4bf624d046b6",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "5df4afd6ed2f7dfd102b8c21f8ced2e7",
-     "grade": true,
-     "grade_id": "correct_count_occurrences",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert count_occurrences([1, 2, 3, 4, 2, 2, 5, 6, 2], 2) == 4"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "bb1784f5-2426-4661-aa13-dba96743ceb5",
-   "metadata": {},
-   "source": [
-    "# Bonus"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "7fdcd705-dc0b-4614-8e27-9ba62f8fe442",
-   "metadata": {},
-   "source": [
-    "### Exercise: Find the maximum value in a list (iterative)\n",
-    "\n",
-    "Check that an empty lists raises a `ValueError` exception with a `\"The list is empty.\"` message."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f9334f32-f760-46c0-a649-c82f267aba5b",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "try:\n",
-    "    result = find_maximum_iterative([])\n",
-    "    assert False, \"Exception not raised\"\n",
-    "except ValueError as e:\n",
-    "    assert str(e) == \"The list is empty.\", f\"Expected error message: 'The list is empty.' but got '{str(e)}'\""
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "c121315a-4aaa-4e04-912f-73f56555be56",
-   "metadata": {},
-   "source": [
-    "### Exercise: Find the maximum value in a list (recursive)\n",
-    "\n",
-    "Witout using the built-in `max` function"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "153e3f05-7598-4920-bc8d-8943cb75e5a8",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# checks if a function uses another function, eg \"max\"\n",
-    "import inspect\n",
-    "\n",
-    "def calls_builtin_max(func):\n",
-    "    source_code = inspect.getsource(func)\n",
-    "    return 'max(' in source_code\n",
-    "\n",
-    "def my_function(lst):\n",
-    "    return max(lst)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "775b7e32-a5ae-431b-9987-fcd3671fd022",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def find_maximum_recursive_no_max_func(L): \n",
-    "    if not L:\n",
-    "        raise ValueError(\"The list is empty.\")\n",
-    "    \n",
-    "    if len(L) == 1:\n",
-    "        return L[0]\n",
-    "    \n",
-    "    rest_max = find_maximum_recursive(L[1:])\n",
-    "    return L[0] if L[0] > rest_max else rest_max"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f76ed657-3288-4b36-9175-21168d2eb761",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert not calls_builtin_max(find_maximum_recursive_no_max_func)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "bbe7023a-aabd-489d-bae6-3b71566e22ef",
-   "metadata": {},
-   "source": [
-    "# Additional tests (do not change)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1c73ad0e-ddc9-483d-85a1-f2a65d04f30b",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert calls_builtin_max(my_function)\n",
-    "assert not calls_builtin_max(find_maximum_iterative)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "8ce960f5-08da-449e-9e6f-dae215bc1b6a",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# generates more examples for a given function\n",
-    "def gen_examples(fnct, n=10):\n",
-    "    return [fnct(i) for i in range(0, n)]"
-   ]
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/exercises/03-lists-search-sort-exercises.ipynb b/exercises/03-lists-search-sort-exercises.ipynb
deleted file mode 100644
index 952d5b38e9a63ccf228129cd0048e88e6a968cbb..0000000000000000000000000000000000000000
--- a/exercises/03-lists-search-sort-exercises.ipynb
+++ /dev/null
@@ -1,659 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "4dbb0dcc",
-   "metadata": {},
-   "source": [
-    "NAME:"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e58599e3-9ab7-4d43-bb22-aeccade424ce",
-   "metadata": {},
-   "source": [
-    "# Lists, search, sort"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "691b3c38-0e83-4bb2-ac90-ef76d2dd9a7a",
-   "metadata": {},
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1095285f-26e2-43ce-a1c5-9358c5256a0b",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "list_complexities = [\"O(1)\", \"O(log(n))\", \"O(n)\", \"O(n^2)\", \"O(nlog(n))\", \"O(n^3)\", \"O(2^n)\", \"O(n!)\", \"O(n^n)\"]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "11a124a7-1279-469a-b091-2833d3fd1a0f",
-   "metadata": {},
-   "source": [
-    "## Exercise 0: Search the index first occurence of a target value\n",
-    "\n",
-    "_Write a Python function `search_list(L, v)` that takes a list `L` and a target element `v` as input. The function should return the index of the first occurrence of the target element in the list `L`._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "665c7b64-428d-468a-860b-65d0d12e98e1",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def search_list(L, target):\n",
-    "    for n, i in enumerate(L):\n",
-    "        if i == target:\n",
-    "            return n\n",
-    "    return -1"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "d776ca94-1ed2-4443-91e2-a1591a1690b8",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "search_list([1, 2, 2], 2)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "e7b5950c-a6f0-4795-995b-903d717f35c9",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert search_list([1, 2, 3, 4, 5], 3) == 2\n",
-    "assert search_list([1, 2, 3, 4, 5], 6) == -1\n",
-    "assert search_list([1, 2, 3, 4, 5], 6) == -1\n",
-    "assert search_list([], 42) == -1\n",
-    "assert search_list([7, 2, 3, 4, 5], 7) == 0\n",
-    "assert search_list([1, 2, 3, 4, 5, 6], 7) == -1"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "9d813205-b709-42ab-b414-6f3fc947022a",
-   "metadata": {},
-   "source": [
-    "## Exercise 1: Search in a list with an odd index\n",
-    "\n",
-    "_Write a Python function `search_list(L, v)` that takes a list `L` and a target element `v` as input. The function should return the index of the first occurrence of the target element in the list `L`._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f3b233ec-7077-479d-9c04-f1a4c35f3111",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "2791444cbfd4f0f74f1ce7f2a330ecec",
-     "grade": false,
-     "grade_id": "search_list",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def search_list(L, target):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f280eeea-4812-4a30-80b5-3fe1cafa9283",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "search_list([1, 2, 2], 3)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "423d2637-8bd6-4e8f-95ff-2765dae5bce7",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "6054e435b1f5635d18f61f94bfb05e62",
-     "grade": true,
-     "grade_id": "correct_correct_search_list",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert search_list([1, 2, 3, 4, 5], 3) == 2\n",
-    "assert search_list([1, 2, 3, 4, 5], 6) == -1\n",
-    "assert search_list([1, 2, 3, 4, 5, 6], 6) == -1\n",
-    "assert search_list([], 42) == -1\n",
-    "assert search_list([7, 2, 3, 4, 5, 7], 7) == 0\n",
-    "assert search_list([1, 2, 3, 4, 5, 6], 6) == -1"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "6d8dc6cd-aad0-42a9-b768-6a1a5289e354",
-   "metadata": {},
-   "source": [
-    "## Exercise 2: Sort a list of tuples\n",
-    "\n",
-    "_Given a list of lists of length N, sort by the N-th element of the list._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "8271ff47-efb4-48a0-ac4c-bba6ede7e578",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "8b5bb88f225392915e460f5f56be2463",
-     "grade": false,
-     "grade_id": "sort_list_of_lists_by_nth_element",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sort_list_of_lists_by_nth_element(L_L, N):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4577bd24-9e50-4172-8246-d1bccfa21618",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "list_of_lists = [[3, 5, 1], [1, 2, 9], [7, 4, 6], [2, 8, 3]]\n",
-    "sorted_list = sort_list_of_lists_by_nth_element(list_of_lists, 2)\n",
-    "print(sorted_list)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ed3cdeed-07fa-461f-b7ae-210e1605ca76",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "b1e4adf55c21c8009a5e869493531cfe",
-     "grade": true,
-     "grade_id": "correct_sort_list_of_lists_by_nth_element",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "list1 = [[3, 5, 1], [1, 2, 9], [7, 4, 6], [2, 8, 3]]\n",
-    "sorted_list1 = sort_list_of_lists_by_nth_element(list1, 2)\n",
-    "assert sorted_list1 == [[3, 5, 1], [2, 8, 3], [7, 4, 6], [1, 2, 9]]\n",
-    "\n",
-    "list2 = [[9, 5, 7], [3, 6, 1], [0, 2, 4], [8, 1, 5]]\n",
-    "sorted_list2 = sort_list_of_lists_by_nth_element(list2, 0)\n",
-    "assert sorted_list2 == [[0, 2, 4], [3, 6, 1], [8, 1, 5], [9, 5, 7]]\n",
-    "\n",
-    "list3 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]\n",
-    "sorted_list3 = sort_list_of_lists_by_nth_element(list3, 1)\n",
-    "assert sorted_list3 == [[1, 2, 3], [4, 5, 6], [7, 8, 9]]\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "0bbda1ba-a5e7-4a1d-a742-84d0215b1e24",
-   "metadata": {},
-   "source": [
-    "## Exercise 3: Access a list element\n",
-    "\n",
-    "_Given an input list `L`, and `index` value, access a given `key` and return the value._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2d6a6f11-d24b-4f0e-a7d2-298243e35c4d",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "df3e8c605c7e96af2267865e04990e5a",
-     "grade": false,
-     "grade_id": "cell-1ab0b636df63501a",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def access_dict_element(L, index, key):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ea0883dc-d08c-40ea-9e0b-4f0a3abc517f",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "example_list = [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]\n",
-    "result = access_dict_element(example_list, 0, 'name')\n",
-    "print(result) "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "88ae441e-58b1-4d6c-a639-530919658d03",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "efa0cb4d52536298b425a5e9d5154374",
-     "grade": true,
-     "grade_id": "correct_access_dict_element",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "example_list = [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]\n",
-    "assert access_dict_element(example_list, 0, 'name') == 'Alice'\n",
-    "assert access_dict_element(example_list, 1, 'city') is None\n",
-    "assert access_dict_element(example_list, 2, 'name') is None\n",
-    "assert access_dict_element(example_list, 0, 'city') is None"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "98405b12-ad61-4007-8c9f-6955d238df41",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "## Exercise 4: Remove Elements from a List\n",
-    "\n",
-    "_Write a Python function `remove_elements(L, condition)` that takes a list `L` and a function `condition` as input._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "e079e47b-2f9e-42d1-a78b-56c92ad84d63",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def is_odd(x):\n",
-    "    return x % 2 != 0"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "536734bd-d4cc-4f83-8042-3c0e774c4034",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "32e7897746d2149cd1f74d8d1897c379",
-     "grade": false,
-     "grade_id": "remove_elements",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def remove_elements(L, condition):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "a65bb6f1-b7c7-4156-ba8b-9b72a25616f3",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
-    "remove_elements(my_list, is_odd)\n",
-    "print(my_list)  # Should print [2, 4, 6, 8]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "254155dc-b271-4881-ac65-5a11d13990ea",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "d60a1be7322087e5612fb15fc5677539",
-     "grade": true,
-     "grade_id": "correct_remove_elements",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "test_list_1 = [12, 5, 18, 9, 25, 3, 15]\n",
-    "remove_elements(test_list_1, lambda x: x > 10)\n",
-    "assert test_list_1 == [5, 9, 3], \"Remove greater than 30\"\n",
-    "\n",
-    "test_list_2 = [-3, 7, -9, 2, 0, -1, 8]\n",
-    "remove_elements(test_list_2, lambda x: x < 0)\n",
-    "assert test_list_2 == [7, 2, 0, 8], \"Remove negative elements\"\n",
-    "\n",
-    "def custom_condition(x):\n",
-    "    return x % 3 == 0\n",
-    "test_list_3 = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
-    "remove_elements(test_list_3, custom_condition)\n",
-    "assert test_list_3 == [1, 2, 4, 5, 7, 8]\n",
-    "\n",
-    "test_list_4 = [42, 99, 101]\n",
-    "remove_elements(test_list_4, lambda x: True)\n",
-    "assert test_list_4 == [], \"Remove all elements\"\n",
-    "\n",
-    "test_list_5 = [10, 20, 30, 40]\n",
-    "remove_elements(test_list_5, lambda x: False)\n",
-    "assert test_list_5 == [10, 20, 30, 40], \"No element to remove\""
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "d75dba4b-ac22-4f2c-9a6c-cf333b1ec5e8",
-   "metadata": {},
-   "source": [
-    "## Exercise 5: Sort a dictionnary by values\n",
-    "\n",
-    "_Create a new sorted list as result._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "556be9d8-b8c3-4f1d-bcb1-8f099968af9d",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "6bfb51c12c41947733534307eb1cf5c4",
-     "grade": false,
-     "grade_id": "sort_dict_by_values",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sort_dict_by_values(input_dict):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()\n",
-    "    return sorted_dict"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3c32c4ee-56f5-46b5-a8b6-b740e6d5fef5",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "test_dict3 = {'c': 3, 'b': 2, 'a': 1}\n",
-    "sorted_dict3 = sort_dict_by_values(test_dict3)\n",
-    "assert sorted_dict3 == {'a': 1, 'b': 2, 'c': 3}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "532e5225-a2d8-4c10-a036-1efde9acc5fd",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "8a4001090e87ce0c5d773621ed0a3ea9",
-     "grade": true,
-     "grade_id": "correct_sort_dict_by_values",
-     "locked": true,
-     "points": 0,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "test_dict = {'banana': 3, 'apple': 1, 'cherry': 2}\n",
-    "sorted_dict = sort_dict_by_values(test_dict)\n",
-    "assert sorted_dict == {'apple': 1, 'cherry': 2, 'banana': 3}\n",
-    "\n",
-    "test_dict2 = {'zebra': 42, 'lion': 7, 'elephant': 15, 'giraffe': 23}\n",
-    "sorted_dict2 = sort_dict_by_values(test_dict2)\n",
-    "assert sorted_dict2 == {'lion': 7, 'elephant': 15, 'giraffe': 23, 'zebra': 42}\n",
-    "\n",
-    "test_dict3 = {'one': 3, 'two': 3, 'three': 3, 'four': 3}\n",
-    "sorted_dict3 = sort_dict_by_values(test_dict3)\n",
-    "assert sorted_dict3 == {'one': 3, 'two': 3, 'three': 3, 'four': 3}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "fef2ad7f-55ef-43f2-991d-5067bb085eb6",
-   "metadata": {},
-   "source": [
-    "## Exercise 6: insertion sort\n",
-    "\n",
-    "Implement the `insertion sort` that operates as follows:\n",
-    "\n",
-    "- Start with an unsorted list.\n",
-    "- Iterate through each element in the list.\n",
-    "- For each element, compare it with the elements to its left in the list.\n",
-    "- Move elements to the right until you find the correct position for the current element.\n",
-    "- Insert the current element into its proper place in the sorted portion of the list.\n",
-    "- Repeat this process for all elements, gradually building a sorted list from left to right."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "51a86852-f8e2-4c05-8053-13fdf2a4832b",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "84421b7199764b6fe3485117b23fb0a1",
-     "grade": false,
-     "grade_id": "insertion_sort",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def insertion_sort(arr):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "fbfa74f1-4675-452f-897b-21b0c7025f81",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "print(insertion_sort([2, 1, 3, 4, 5]))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "266e89e0-4b59-441f-bb67-69ad4e35e2a9",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "dc6fc6f16aa2c62a5e1e39382106b0bf",
-     "grade": true,
-     "grade_id": "correct_insertion_sort",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# Test case 2: Already sorted list\n",
-    "arr = [1, 2, 3, 4, 5]\n",
-    "assert insertion_sort(arr) == arr\n",
-    "\n",
-    "# Test case 3: Reverse sorted list\n",
-    "arr = [5, 4, 3, 2, 1]\n",
-    "assert insertion_sort(arr) == [1, 2, 3, 4, 5]\n",
-    "\n",
-    "# Test case 4: Random order list\n",
-    "arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]\n",
-    "assert insertion_sort(arr) == [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "ab78dd44-bb6a-451d-8642-223639d31bf9",
-   "metadata": {},
-   "source": [
-    "## Bonus\n",
-    "\n",
-    "Extra tasks:\n",
-    "\n",
-    "- add exceptions https://docs.python.org/3/library/exceptions.html\n",
-    "- add more test cases"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "d7622873-8c3b-496a-977c-5413309653e3",
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/exercises/04-05-06-programming-strategies-exercises.ipynb b/exercises/04-05-06-programming-strategies-exercises.ipynb
deleted file mode 100644
index edfeb6156960fc18323d5787acff2e9d36fde2c4..0000000000000000000000000000000000000000
--- a/exercises/04-05-06-programming-strategies-exercises.ipynb
+++ /dev/null
@@ -1,856 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "a8fca59b",
-   "metadata": {},
-   "source": [
-    "NAME:"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e58599e3-9ab7-4d43-bb22-aeccade424ce",
-   "metadata": {},
-   "source": [
-    "# Programming strategies"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "691b3c38-0e83-4bb2-ac90-ef76d2dd9a7a",
-   "metadata": {},
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "9d813205-b709-42ab-b414-6f3fc947022a",
-   "metadata": {},
-   "source": [
-    "## Exercise 1: tribonacci\n",
-    "\n",
-    "Here is an implementation of the Tribonacci sequence (similar to the Fibonacci) defined as:\n",
-    "\n",
-    "$T(n) = T(n-1) + T(n-2) + T(n-3)$\n",
-    "\n",
-    "_Explain the role of the `tab` variable; write some tests._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f3b233ec-7077-479d-9c04-f1a4c35f3111",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def tribonacci(n: int) -> int:\n",
-    "        \n",
-    "        if(n==0):\n",
-    "            return 0\n",
-    "        if(n==1):\n",
-    "            return 1\n",
-    "        if(n==2):\n",
-    "            return 1\n",
-    "        \n",
-    "        tab=[0 for i in range(n+1)]\n",
-    "        tab[0]=0\n",
-    "        tab[1]=1\n",
-    "        tab[2]=1\n",
-    "        \n",
-    "        for i in range(3, n+1):\n",
-    "            tab[i]=tab[i-1]+tab[i-2]+tab[i-3]\n",
-    "        \n",
-    "        return tab[n]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f280eeea-4812-4a30-80b5-3fe1cafa9283",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tribonacci(11)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "423d2637-8bd6-4e8f-95ff-2765dae5bce7",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "b833cc54e7ba02d4708b3893c582aae4",
-     "grade": false,
-     "grade_id": "cell-9e7356aa23ccfb4c",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "b2b31dca-a19a-46cf-b0de-4feec6afa083",
-   "metadata": {},
-   "source": [
-    "## Exercice 2: find two numbers with a given sum\n",
-    "\n",
-    "_Find two numbers in an array `nums` that add up to a specific target value `target`. Return a list of the values index._ \n",
-    "\n",
-    "_Tip: make sure you do not use twice the same array element._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f5a964df-958e-4758-8ca2-1139c59a7585",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "4dc958b6b1ee7b6ff3ddf02ea4805aea",
-     "grade": false,
-     "grade_id": "two_sum",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def two_sum(nums, target: int):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1cec37b0-5d27-4973-b53a-053a46992c0c",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "two_sum([1, 2, 3, 4, 5], 4)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "395cb69f-b99a-4c60-88f5-11216a5ec857",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "2007c6b25ddb1a5c4fa117a0ed571b25",
-     "grade": true,
-     "grade_id": "correct_two_sum",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert two_sum([2, 7, 11, 15, 19], 9) == [0, 1]  # 2 + 7 = 9\n",
-    "assert two_sum([3, 2, 4], 6) == [1, 2]       # 2 + 4 = 6\n",
-    "assert two_sum([3, 3], 6) == [0, 1]          # 3 + 3 = 6\n",
-    "assert two_sum([3, 3], 123) == -1            # not possible"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "dc4f4361-5dee-4e19-b3fd-d18ea40d341e",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "## Exercice 3: find the minimum distance between two points\n",
-    "\n",
-    "_Given a list of points find the minimum distance between all the pairs of points._\n",
-    "\n",
-    "- write a `dist`function using \n",
-    "- define a `closest_point_naive`function using `math.inf`as initial value\n",
-    "\n",
-    "Tip: make sure you do not use the same point twice!"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f73f28a4-d39c-497d-9cbb-1c4edd1c628f",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import math"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0be305c3-c054-4092-b041-bd7e705e2178",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "e00cddc47958defae9cbbdc89056c923",
-     "grade": false,
-     "grade_id": "cell-8738237c4c6682e4",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def dist(point1, point2):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "c0e25948-eefd-4cb0-a893-c3d5e34ff0ee",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "d578bae1b972f9331bf0c4e8918312da",
-     "grade": false,
-     "grade_id": "cell-9ca280911ed42034",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def closest_point_naive(P):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "965d8274-470e-4a3e-8b88-60d458de74e2",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "points = [(1, 2), (4, 6), (7, 8), (3, 5)]\n",
-    "closest_point_naive(points)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5d875175-45c3-4594-a434-23e15cfb88f7",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "7a40093d879cf398bc8ccc735d221027",
-     "grade": true,
-     "grade_id": "cell-618f956021833284",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "points1 = [(1, 2), (4, 6), (0, 0), (0, 0)]\n",
-    "closest_point_naive(points1)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "755116cb-456e-48ad-8dfe-bd72617488d9",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert math.isclose(closest_point_naive(points1), 0.0, rel_tol=1e-9)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "4d521622-f4b7-4859-b501-2583b943d0e7",
-   "metadata": {},
-   "source": [
-    "## Exercice 4: display the minimum distance\n",
-    "\n",
-    "_Update the previous function to take a single list of points `P`as input and return the closest points and draw the line that connects them._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "a5902565-9c98-482a-8e63-9cc37214beb2",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from matplotlib import pyplot as plt\n",
-    "import random\n",
-    "\n",
-    "points_count = 10\n",
-    "x = [random.gauss(0, 1) for _ in range(points_count)]\n",
-    "y = [random.gauss(0, 1) for _ in range(points_count)]\n",
-    "\n",
-    "def draw_points(x, y):\n",
-    "    color = \"blue\"\n",
-    "    plt.figure(figsize=(10, 7))\n",
-    "    _ = plt.plot(x, y, '.', markersize=14, color=color)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "e35557a8-54cb-4324-b280-4479835685db",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "draw_points(x, y)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "6c504c53-d3fc-44a1-904c-49ceff572638",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "bc0203ebd28b691616fc04b52f0c6240",
-     "grade": false,
-     "grade_id": "closest_point_naive_pair",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def closest_point_naive_pair(P):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()\n",
-    "    return closest_point1, closest_point2"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4266685c-19f9-4d2f-bb71-4d047bb54787",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "832d9b24ce34dec082dff9b7e327c869",
-     "grade": true,
-     "grade_id": "correct_closest_point_naive_pair",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from matplotlib import pyplot as plt\n",
-    "import random\n",
-    "import math\n",
-    "\n",
-    "points_count = 10\n",
-    "color = \"blue\"\n",
-    "x = [random.gauss(0, 1) for _ in range(points_count)]\n",
-    "y = [random.gauss(0, 1) for _ in range(points_count)]\n",
-    "\n",
-    "points = list(zip(x, y))\n",
-    "\n",
-    "closest_point1, closest_point2 = closest_point_naive_pair(points)\n",
-    "\n",
-    "plt.figure(figsize=(10, 7))\n",
-    "_ = plt.plot(x, y, '.', markersize=14, color=color)\n",
-    "plt.plot([closest_point1[0], closest_point2[0]], [closest_point1[1], closest_point2[1]], '-', color='red', linewidth=2)\n",
-    "\n",
-    "plt.show()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "bcec1dfc-6ce9-4b08-bc1c-f8d0887aa876",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "points1 = [(0, 0), (1, 1), (3, 3), (5, 5)]\n",
-    "closest_point_naive_pair(points1)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "aad82edd-144d-4117-9ee6-485b9e739251",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert closest_point_naive_pair(points1) == ((0, 0), (1, 1))"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "52ede988-1834-489d-9cca-e9882e90f9af",
-   "metadata": {},
-   "source": [
-    "## Exercice 5: implement the merge sort\n",
-    "\n",
-    "0. Find a base case\n",
-    "1. Finding the mid of the array \n",
-    "2. Divide the array elements  into 2 halves \n",
-    "3. Sorting the first half and the second half independantly\n",
-    "4. merge by copying arrays into a final one"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "b835049a-27a7-4d45-b819-b9e4d813fdcf",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "7e5d1e25bd4a7d8aceca67ae23771b79",
-     "grade": false,
-     "grade_id": "merge_sort",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def merge_sort(L):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4ad36fe3-7e9e-4ae8-9df6-f816e24d6c28",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "merge_sort([3, 6, 1])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "85865859-828f-4a6b-aad8-51ba0de8ac5b",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "06abbc717c29465f92ec2b6bc8dc596b",
-     "grade": true,
-     "grade_id": "correct_merge_sort",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert merge_sort([4, 2, 3]) == sorted([4, 2, 3])\n",
-    "assert merge_sort([7, 2, 1]) == [1, 2, 7]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e5b7304d-7b64-42df-9465-8f4491525a8b",
-   "metadata": {},
-   "source": [
-    "# Exercice 6: organize a schedule\n",
-    "\n",
-    "_Propose a greedy algorithm that returns a list of time slots that do not overlap._\n",
-    "\n",
-    "In this question you may prioritize the ones that end last, so you may sort by [reverse order](https://docs.python.org/3/howto/sorting.html)."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "e0ed0841-1255-4bdb-b7f8-e689c2a953af",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "240106e7faa5c05dfe9e32f64f68e3cf",
-     "grade": false,
-     "grade_id": "interval_scheduling",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def interval_scheduling(intervals):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "d6a50280-f016-4686-8515-1b4a136c0fd9",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "interval_scheduling([(0, 2), (2, 4), (1, 3)])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "bd38d673-077d-44b1-b81c-ac7448f5c01c",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "d8a22346b92125746d141cee329408f1",
-     "grade": true,
-     "grade_id": "correct_interval_scheduling",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert interval_scheduling([(0, 2), (2, 4), (1, 3)]) == [(0, 2), (2, 4)]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "de2c9857-9925-4477-96e4-341fa5bc4ec8",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert interval_scheduling([(0, 2), (2, 4), (1,3)]) == [(0, 2), (2, 4)]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "c142c3b3-2f01-48d0-8596-601bb133542b",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "Now you may prioritize the ones that are the longest."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "095836b8-2612-4d58-a9ce-b7968489418c",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "b448fda533da03916276f3f7701f1a59",
-     "grade": false,
-     "grade_id": "interval_scheduling_longest",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def interval_scheduling_longest(intervals):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "c87ae1e2-7497-4920-9597-d1b3cddf8580",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "interval_scheduling_longest([(0, 4), (3, 5), (5, 7)])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "afcf3a69-aa36-4b71-93a8-218337ed88b9",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "5eb8ff6c627cab5c24af63f377eb221e",
-     "grade": true,
-     "grade_id": "correct_interval_scheduling_longest",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert interval_scheduling_longest([(0, 4), (3, 5), (5, 7)]) == [(0, 4), (5, 7)]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a559e4db-9ef2-4d20-bb9f-cb638d8c1f24",
-   "metadata": {},
-   "source": [
-    "# Exercice 7: knapsack problem\n",
-    "\n",
-    "Propose a greedy solution for the Kanpsack problem defined as follows:\n",
-    "\n",
-    "$\\sum_{i=1}^n w_i x_i \\leq W$ and $x_i \\in \\{0,1,2,\\dots,c\\}$\n",
-    "\n",
-    "Which selects the item with the least weight that can fit within the knapsack's capacity at each step "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5833bde3-1960-43ad-b140-381ac6dd228c",
-   "metadata": {},
-   "source": [
-    "`W:` The maximum weight capacity of the knapsack.\n",
-    "\n",
-    "`w:` A list of item weights.\n",
-    "\n",
-    "`n:` The number of items available to choose from.\n",
-    "\n",
-    "Tip:\n",
-    "\n",
-    "- Initialize with all the item indices of the remaining items\n",
-    "- Start with an empty knapsack of total weight 0\n",
-    "- Create a loop that selects the best item from the remaining (with least weight)\n",
-    "- Add the item to the knapsack and remove it from the list of items\n",
-    "- Return the total weight and list of items used"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "46947633-3f5f-420b-b416-500a0dab4fcb",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "959fdc68a051b0090f4ead159f3356df",
-     "grade": false,
-     "grade_id": "cell-0bf75b2bfe8e2e4c",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def greedy_knapsack(W, w):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "737df134-4ee1-49a9-9034-da3b0267ae84",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "weights = [5, 3, 4, 2]\n",
-    "max_weight = 5\n",
-    "\n",
-    "result, selected_weights = greedy_knapsack(max_weight, weights)\n",
-    "print(\"Total weight:\", result, \"and selected weights:\", selected_weights)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "a66c6e52-2d60-4423-bc3a-a3dcef38da26",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert greedy_knapsack(5, [2, 3, 4, 5]) == (5, [2, 3])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "37ff64e9-fc2c-4593-b85a-d83982445b9d",
-   "metadata": {},
-   "source": [
-    "Propose a dynamic programming solution following the general case:\n",
-    "\n",
-    "$\n",
-    "dp[i][w] = \n",
-    "\\begin{cases}\n",
-    "0 & \\text{if } i = 0 \\text{ or } w = 0 \\\\\n",
-    "dp[i-1][w] & \\text{if } w_i > w \\\\\n",
-    "\\max(dp[i-1][w], w_i + dp[i-1][w - w_i]) & \\text{otherwise}\n",
-    "\\end{cases}$"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2be5f2f7-d9a5-4cf0-afe4-5a5a54ee0434",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "f5b1cc2b31e32e2468be56b84bf67cb3",
-     "grade": false,
-     "grade_id": "cell-5dc5571a7aca5b0f",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def dynamic_knapsack(W, wt):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5adf0e0e-73c4-4656-b546-5b02347f1a28",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "weights = [2, 3, 4, 5]\n",
-    "max_weight = 5\n",
-    "result, selected_weights = dynamic_knapsack(max_weight, weights)\n",
-    "print(\"Total weight:\", result, \"and selected weights:\", selected_weights)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ef20e870-fcba-4610-bf22-37af0b0691a0",
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/exercises/07-stacks-queues-exercises.ipynb b/exercises/07-stacks-queues-exercises.ipynb
deleted file mode 100644
index 0f00dda13680d09e14a9e78b665d8a777f5dc5f8..0000000000000000000000000000000000000000
--- a/exercises/07-stacks-queues-exercises.ipynb
+++ /dev/null
@@ -1,412 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "7b900342",
-   "metadata": {},
-   "source": [
-    "NAME:"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "2f1f2dcd-96a9-45ef-90a6-4ad488635679",
-   "metadata": {},
-   "source": [
-    "# Stacks and queues"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "b9bd540c-dd15-49ac-bfbd-f2e758688a85",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "03a0653e-65c2-4e79-9e83-31765cf19098",
-   "metadata": {},
-   "source": [
-    "## Exercise 1: Reverse a string using a Stack\n",
-    "\n",
-    "_Use the `Stack` below to reverse a string given as input._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4932473d-2734-4e81-b777-ca10decfd9e8",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class Stack:\n",
-    "    def __init__(self):\n",
-    "        self.items = []\n",
-    "\n",
-    "    def push(self, item):\n",
-    "        self.items.append(item)\n",
-    "\n",
-    "    def pop(self):\n",
-    "        if not self.is_empty():\n",
-    "            return self.items.pop()\n",
-    "\n",
-    "    def peek(self):\n",
-    "        if not self.is_empty():\n",
-    "            return self.items[-1]\n",
-    "\n",
-    "    def is_empty(self):\n",
-    "        return len(self.items) == 0"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "8b77ae34-ef7c-4664-94e0-8928156f2224",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "128a37273e0e5da052abe4bf08bb1c27",
-     "grade": false,
-     "grade_id": "cell-5b0828e97507162e",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def reverse_string(s):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "63719c8e-f60c-4544-8e41-cb6380ae4bcf",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "reverse_string(\"Hello\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "81e93620-0664-4a9d-ba5f-894937c9769e",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert reverse_string(\"Hello\") == \"olleH\" "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "81df9b1e-cfe5-4b69-96a5-c8065259cc7d",
-   "metadata": {},
-   "source": [
-    "## Exercise 2: Check if a word is a palindrom (using a Stack)\n",
-    "_A palindrome is a sequence of characters that reads the same forward and backward._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "cf6fbdd5-53c5-45c2-a0c5-a5ed845c4f81",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "048d788477e620bf78240329c0dd8771",
-     "grade": false,
-     "grade_id": "is_palindrome",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def is_palindrome(s):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "586bafba-2fbb-4833-b2e3-609db9b28fbf",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "is_palindrome(\"ABA\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "d0005a10-9152-4aa5-a94b-fcbff1bd2281",
-   "metadata": {
-    "deletable": false,
-    "editable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "4165b33ba9b75546b0edd15216e61e4f",
-     "grade": true,
-     "grade_id": "correct_is_palindrome",
-     "locked": true,
-     "points": 0,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert is_palindrome(\"ABA\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "f767bf25-9f4f-4a0d-8cb9-b729bbec5c27",
-   "metadata": {},
-   "source": [
-    "## Exercise 3: Implement a min-heap\n",
-    "\n",
-    "Use a `PriorityQueue` to return the smallest element when using `pop` of a stack (or a queue). "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ddcccaf6-d235-4327-826f-7a62a4c23f28",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from queue import PriorityQueue"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2da2db1e-f55d-43b4-877f-96ef944818e8",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# how to use the queue module\n",
-    "priority_queue = PriorityQueue()\n",
-    "priority_queue.put((3, 'apple'))\n",
-    "priority_queue.put((1, 'banana'))\n",
-    "priority_queue.put((2, 'cherry'))\n",
-    "element = priority_queue.get()\n",
-    "print(element)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "804ea32d-5bf8-42b9-ae52-6318b26f4065",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "7f6b90fc037aa2a24fa9ce3b4dfca6dd",
-     "grade": false,
-     "grade_id": "cell-4b9a5ecdee87514e",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1b2d28c4-277b-44fa-b7e8-590aa00f8f70",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "min_heap = MinHeap()\n",
-    "min_heap.insert(5)\n",
-    "min_heap.insert(3)\n",
-    "min_heap.insert(8)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ed61bced-f000-41c6-8ecd-d669b4edb700",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert min_heap.pop() == 3\n",
-    "assert min_heap.peek() == 5\n",
-    "assert min_heap.peek() == 5"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a445d290-b04f-49b5-a8e7-2c6e259daf58",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "## Exercise 4: Evaluate a postfix expression\n",
-    "\n",
-    "_Write a code that given the following expression, provides the following evaluation (using arthmetic operations over numerical values)._\n",
-    "\n",
-    "Expression: `\"3 4 +\"`\n",
-    "Evaluation: `3 + 4 = 7`\n",
-    "\n",
-    "First step: write a function `apply_operator` that applies an operation (ie + - * /) over two elements."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4cc7f805-0887-4422-b6b7-3d591d0df1fb",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "eb88296bc1de3c5dd7c68059e0a071e8",
-     "grade": false,
-     "grade_id": "cell-8c5106f02f243455",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def apply_operator(op, b, a):\n",
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e68bdf7c-ca08-4553-9874-8bd9038fd4b5",
-   "metadata": {},
-   "source": [
-    "Solution in pseudo-code:\n",
-    "- Split the input expression in to a list of tokens\n",
-    "- If not an operator\n",
-    "    - Add the value to the stack\n",
-    "- If an operator \n",
-    "    - Make sure there is enough parameters `a` and `b`\n",
-    "    - Pop `a` and `b`\n",
-    "    - Apply `apply_operator` on `a` and `b`\n",
-    "    - Store the result in the stack"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "e792c90d-1b38-47f5-9879-399debc934b9",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "73960d3c6b85c2efc0ad8e298e2649b7",
-     "grade": false,
-     "grade_id": "cell-e9236618b265b34f",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def evaluate_postfix(expression):\n",
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ea6e4840-1b7e-4265-b37d-e8c45ea6b3ed",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "postfix_expression = \"3 4 + 2 *\"\n",
-    "print(evaluate_postfix(postfix_expression))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0dc4dff8-089b-46a6-a08d-f53ee2fe72c3",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert evaluate_postfix(\"3 4 + 2 *\") == 14\n",
-    "assert evaluate_postfix(\"4 2 3 5 * + *\") == 68 # (4 * (2 + (3 * 5))\n",
-    "assert evaluate_postfix(\"8 4 / 6 2 * +\") == 14 # ((8 / 4) + (6 * 2))"
-   ]
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/exercises/08-binary-trees-exercises.ipynb b/exercises/08-binary-trees-exercises.ipynb
deleted file mode 100644
index 7c840cd461e117625ee06cf01e70e72989de9a24..0000000000000000000000000000000000000000
--- a/exercises/08-binary-trees-exercises.ipynb
+++ /dev/null
@@ -1,425 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "91c9c0b9",
-   "metadata": {},
-   "source": [
-    "NAME:"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "3bae696a-8e88-4a34-89f6-a0f4d9551e9b",
-   "metadata": {},
-   "source": [
-    "# Binary trees\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "7c7461c1-fe15-405b-a2c9-709e6f9c3743",
-   "metadata": {},
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a2428808-27d5-4d42-84b8-01632b1271dd",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "## Exercise 1: Write the code for this binary tree\n",
-    "\n",
-    "_Use a `dict()` data structure for the list of nodes._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "83b91119-09f7-4cba-a87b-19fc4a793e91",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from graphviz import Digraph\n",
-    "\n",
-    "dot = Digraph()\n",
-    "\n",
-    "dot.node_attr['shape'] = 'circle'\n",
-    "\n",
-    "dot.node('0', label='0')  # Root\n",
-    "dot.node('1')\n",
-    "dot.node('2')\n",
-    "dot.node('3')\n",
-    "dot.node('4')\n",
-    "dot.node('5')\n",
-    "\n",
-    "dot.edge('0', '1')\n",
-    "dot.edge('1', '4')\n",
-    "dot.edge('1', '5')\n",
-    "\n",
-    "dot.edge('0', '2', color='red')\n",
-    "dot.edge('2', '3', color='red')\n",
-    "\n",
-    "\n",
-    "dot # Render the graph"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "1fca57f5-4b3c-4ad8-a4c0-9d1de647abf9",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "_Use a `Dict` data structure for nodes and also for edges edges._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "fa1bce0f-7b06-4d20-8a1b-990bcd03bda9",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "e4c7bf49dab0dfd7b602a4c0c683b731",
-     "grade": false,
-     "grade_id": "cell-0f290aab7c180fb7",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "cb16382b-e00d-498a-bab2-0b251f93d147",
-   "metadata": {},
-   "source": [
-    "_Use a `Tuple` data structure for nodes and edges._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "a4cbc1d4-5adc-4cda-9c2a-24101bd1bed9",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "7738eb399dd344478be29fefebaf1ec2",
-     "grade": false,
-     "grade_id": "cell-ce11e1828bd74e71",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "fb0e9336-603c-49c4-9617-9ccecdbf7156",
-   "metadata": {},
-   "source": [
-    "# Exercise: binary search tree\n",
-    "\n",
-    "_We assume we have a binary search tree (BST). Its main property is that for every node, the value of the left children is less than the value of the right children._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "02513514-0e1b-4c0d-a5fd-ac6b571231b7",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class Node:\n",
-    "    def __init__(self, value):\n",
-    "        self.value = value\n",
-    "        self.left = None\n",
-    "        self.right = None\n",
-    "    def __str__(self):\n",
-    "        return str(self.value)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "055d2cea-4e45-402d-baf8-e50939c94132",
-   "metadata": {},
-   "source": [
-    "Write an `insert` function inserts a value in a tree so it preserves the BST property."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "6492983d-054c-4488-b8ff-57b3878f5b7e",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "bd38bd2d4979e4e3054b3e37a4ca1ed1",
-     "grade": false,
-     "grade_id": "cell-b636f3646835e810",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def insert(root, value):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "7c2a2f74-a8b8-4cd6-a881-9181efdb7a64",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "a = Node(2)\n",
-    "insert(a, 3)\n",
-    "insert(a, 4)\n",
-    "insert(a, 1)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "10b6d8de-fb38-41e3-92b9-957f04a6f1e4",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "visualize_oop(a)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "07ca3602-96fd-43d7-b7ac-54f92124a11d",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "# Exercice: calculate the height using OOP"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2e65ec3d-8e90-4e25-befb-d779713fa3f2",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class Node:\n",
-    "    def __init__(self, value, l = None, r = None):\n",
-    "        self.value = value\n",
-    "        self.left = l\n",
-    "        self.right = r"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "3bd05d7e-7e0c-4042-9aac-616960849de9",
-   "metadata": {},
-   "source": [
-    "In a recursive way:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "c323b9af-98f6-45d6-9ee2-cffde39a2a16",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "42c8cd4604ffd18d8666aabe5247c397",
-     "grade": false,
-     "grade_id": "cell-b19dae2393fee8a2",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def recursive_tree_height(node):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9527fa59-87cf-4216-a7dc-ad0aa3330d4c",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert recursive_tree_height(Node(2)) == 0\n",
-    "assert recursive_tree_height(Node(2, Node(3))) == 1\n",
-    "assert recursive_tree_height(Node(2, Node(3, Node(4)))) == 2"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "7b46712d-472b-4997-90b4-acda29a17fb9",
-   "metadata": {},
-   "source": [
-    "In an interative way:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "6cd2bdcf-d4ad-4103-88ed-ced3fb45f4e8",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "1afd752578f9f00f7fb8ab9b3a28226a",
-     "grade": false,
-     "grade_id": "cell-8cc9bfd56a6fcde6",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def iterative_tree_height(root):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "dac217fa-c9db-46ca-91a3-a834c3d0aa38",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert iterative_tree_height(Node(2)) == 0\n",
-    "assert iterative_tree_height(Node(2, Node(3))) == 1\n",
-    "assert iterative_tree_height(Node(2, Node(3, Node(4)))) == 2"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5e50ca4a-6aaf-4620-924a-eb6d8a00efaf",
-   "metadata": {},
-   "source": [
-    "# Utils"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0c319da6-cee4-447f-b178-0ed04da67273",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from graphviz import Digraph\n",
-    "from IPython.display import display\n",
-    "\n",
-    "class Node:\n",
-    "    def __init__(self, value, l = None, r = None):\n",
-    "        self.value = value\n",
-    "        self.left = l\n",
-    "        self.right = r\n",
-    "\n",
-    "def visualize_oop(root):\n",
-    "    def build(node, dot=None):\n",
-    "        if dot is None:\n",
-    "            dot = graphviz.Digraph(format='png')\n",
-    "\n",
-    "        if node is not None:\n",
-    "            dot.node(str(node.value))\n",
-    "\n",
-    "            if node.left is not None:\n",
-    "                dot.edge(str(node.value), str(node.left.value))\n",
-    "                build(node.left, dot)\n",
-    "\n",
-    "            if node.right is not None:\n",
-    "                dot.edge(str(node.value), str(node.right.value))\n",
-    "                build(node.right, dot)\n",
-    "\n",
-    "        return dot\n",
-    "\n",
-    "    return build(root)\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "b5866309-ceba-4d71-a2e0-5df6e5e18b25",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "visualize_oop(Node(3, Node(2)))"
-   ]
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/lectures/01-data-structures-complexity slides.pdf b/lectures/01-data-structures-complexity slides.pdf
index 336e8898a2dafa31c6f24ad421dc3481a25decc3..626c5a79abd8ccfa2e1b75bb5a4aa625c32fcc77 100644
Binary files a/lectures/01-data-structures-complexity slides.pdf and b/lectures/01-data-structures-complexity slides.pdf differ
diff --git a/solutions/02-recursion-exercises.ipynb b/solutions/02-recursion-exercises.ipynb
deleted file mode 100644
index 9e5ff999c0cb675c277eea94e564470877bcd2ab..0000000000000000000000000000000000000000
--- a/solutions/02-recursion-exercises.ipynb
+++ /dev/null
@@ -1,1221 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "a4e4fad3",
-   "metadata": {
-    "slideshow": {
-     "slide_type": "slide"
-    }
-   },
-   "source": [
-    "# Recursion"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a8adef9b",
-   "metadata": {
-    "slideshow": {
-     "slide_type": "skip"
-    }
-   },
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "id": "0dfe1da3-b50b-49c0-aaff-483616e13863",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "list_complexities = [\"O(1)\", \"O(log(n))\", \"O(n)\", \"O(n^2)\", \"O(nlog(n))\", \"O(n^3)\", \"O(2^n)\", \"O(n!)\", \"O(n^n)\"]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "568202fd",
-   "metadata": {
-    "slideshow": {
-     "slide_type": "subslide"
-    }
-   },
-   "source": [
-    "### Exercise 0: Find the maximum value in a list (iterative)\n",
-    "\n",
-    "Write a function `find_maximum_iterative` that takes a list of numbers as input and returns the maximum value in the list. For this question, you are  not allowed to use built-in functions like `max()`."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "id": "431fe8c1-91d1-40f3-a7a4-f4a3770a4a01",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "find_maximum_iterative",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def find_maximum_iterative(L):\n",
-    "    ### BEGIN SOLUTION    \n",
-    "    if len(L) == 0:\n",
-    "        raise ValueError(\"The list is empty.\")\n",
-    "\n",
-    "    max_val = L[0]\n",
-    "    for num in L:\n",
-    "        if num > max_val:\n",
-    "            max_val = num\n",
-    "    return max_val\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "id": "f6baae3c-3660-4add-ab4b-48016cba3030",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "9"
-      ]
-     },
-     "execution_count": 4,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "find_maximum_iterative([1, 3, 5, 7, 9])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "id": "e68b3e9a-418f-4950-9f27-18bb0fe90794",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_find_maximum_iterative",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert find_maximum_iterative([1, 3, 5, 7, 9]) == 9\n",
-    "assert find_maximum_iterative([-1, -5, -3]) == -1\n",
-    "assert find_maximum_iterative([42]) == 42\n",
-    "assert find_maximum_iterative([4, 8, 8, 2, 7]) == 8\n",
-    "assert find_maximum_iterative([-10, -5, -8, -2, -7]) == -2"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "612dc873-419b-42c5-be36-0accd03ffa79",
-   "metadata": {},
-   "source": [
-    "### Exercise 1: Find the maximum value in a list (recursive)\n",
-    "\n",
-    "Write a recursive version of the previous function; you may use the `max()` function for the recursive call."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "id": "07668fd8",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "find_maximum_recursive",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def find_maximum_recursive(L):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if len(L) == 1:\n",
-    "        return L[0]\n",
-    "    else:\n",
-    "        return max(L[0], find_maximum_recursive(L[1:]))\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "id": "f9784710-4b2b-434c-bc47-da46fa410749",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "9"
-      ]
-     },
-     "execution_count": 7,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "find_maximum_recursive([1, 3, 5, 7, 9])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "id": "9b0161f8-0539-4e5e-921c-1886e61c0783",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_find_maximum_recursive",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert find_maximum_iterative([-10, -5, -8, -2, -7]) == find_maximum_recursive([-10, -5, -8, -2, -7])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "005efd41-baa1-4505-b80e-3644d61ea094",
-   "metadata": {},
-   "source": [
-    "### Exercise 2: Sum of digits"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "id": "de424156-0b9b-41d0-8e38-ce335f35cec0",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "sum_of_digits",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sum_of_digits(n):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if n < 10:\n",
-    "        return n\n",
-    "    else:\n",
-    "        return n % 10 + sum_of_digits(n // 10)\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "id": "cec0caca-cb2c-4e4d-b004-27b3cf2ff611",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "1"
-      ]
-     },
-     "execution_count": 10,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "sum_of_digits(10)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "id": "bf276ca2-48ed-4e87-80f2-776f54b7062b",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_sum_of_digits",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert sum_of_digits(10) == sum_of_digits(100000)\n",
-    "assert sum_of_digits(0) == 0\n",
-    "assert sum_of_digits(123) == 6"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e2de630a-f9bd-4d45-959b-430e34cc9044",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "### Exercise 3: Calculate the power"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "id": "abca03a0-7bcd-4ee6-b109-ff2f2da52bb6",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "power",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def power(base, exponent):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if exponent == 0:\n",
-    "        return 1\n",
-    "    else:\n",
-    "        return base * power(base, exponent - 1)\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "id": "abddd3b1-f75f-4cb6-a09e-54eed489c5b0",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "1024"
-      ]
-     },
-     "execution_count": 13,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "power(2, 10)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "id": "8a6605fe-4f6f-45de-84a3-7601e2e2e6f6",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_power",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert power(2, 10) == 1024\n",
-    "assert power(2, 0) == 1\n",
-    "assert power(5, 3) == 125"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "715100d3-fc21-49b9-a66d-b5243b4a279d",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "### Exercise 4: Reverse a string\n",
-    "\n",
-    "In a recursive way:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "id": "ddc9826a-0863-4777-a08d-81b66652b5a5",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "reverse_string",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def reverse_string(s):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if len(s) == 0 or len(s) == 1:\n",
-    "        return s\n",
-    "    else:\n",
-    "        return reverse_string(s[1:]) + s[0]\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "id": "13acad7e-d03c-4ea6-ad86-baf02e0910eb",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'niamoR'"
-      ]
-     },
-     "execution_count": 16,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "reverse_string(\"Romain\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
-   "id": "453c8e04-6cd9-4581-a206-dd479b6115cd",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_reverse_string",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert reverse_string(\"\") == \"\"\n",
-    "assert reverse_string(\"AA\") == \"AA\"\n",
-    "assert reverse_string(\"ABC\") == \"CBA\""
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "c1587148-f816-4af2-8f3a-6d8a8480d54d",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "In an iterative way:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 21,
-   "id": "159b6d78-03ae-4cf8-8545-e822b7160b32",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-ead02fa889911e42",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def iterative_reverse_string(s):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    reversed_str = \"\"\n",
-    "    for char in s:\n",
-    "        reversed_str = char + reversed_str\n",
-    "    return reversed_str\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 22,
-   "id": "0dcdbd99-5f57-4d1c-bc31-8f8afc617d0e",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'niamoR'"
-      ]
-     },
-     "execution_count": 22,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "iterative_reverse_string(\"Romain\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 23,
-   "id": "43e10b0c",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "assert iterative_reverse_string(\"Romain\") == reverse_string(\"Romain\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5ab8f3c9-ddee-45ab-a013-fdd67d9853e0",
-   "metadata": {},
-   "source": [
-    "### Example 5: convert an interative suite into a recursive tail function\n",
-    "\n",
-    "_A recursive tail function is a function where the last operation is the recursive call._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 24,
-   "id": "219add7f",
-   "metadata": {
-    "slideshow": {
-     "slide_type": "subslide"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sequence(n):\n",
-    "    u = 1\n",
-    "    while n > 0:\n",
-    "        u = 2 * u + 1\n",
-    "        n -= 1\n",
-    "    return u"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 25,
-   "id": "0787df24-8234-4286-b910-5f9e456dd279",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The result is 15\n"
-     ]
-    }
-   ],
-   "source": [
-    "print(\"The result is {}\".format(sequence(3)))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 26,
-   "id": "9c17cf1b-6d05-4589-af2b-c05cfcc33202",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "sequence_recursive_tail",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sequence_recursive_tail(n):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if n == 0:\n",
-    "        return 1\n",
-    "    return 2 * sequence_recursive_tail(n - 1) + 1\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 27,
-   "id": "43507c43-de61-414d-b389-c0a771ad9e0c",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The result is still 15\n"
-     ]
-    }
-   ],
-   "source": [
-    "print(\"The result is still {}\".format(sequence_recursive_tail(3)))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 28,
-   "id": "dd923b7c-0cab-4678-8dc3-aad2ab9b25f9",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_sequence_recursive_non_tail",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "slideshow": {
-     "slide_type": "slide"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert sequence_recursive_tail(3) == 15"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "3c28b36a",
-   "metadata": {
-    "slideshow": {
-     "slide_type": "subslide"
-    }
-   },
-   "source": [
-    "### Example 6: check if a word is a palindrom\n",
-    "\n",
-    "Check if a word can be read backwards."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 29,
-   "id": "51bb3d08",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "annagram_rec",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def palindrom_rec(word):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if len(word) < 2: \n",
-    "        return True\n",
-    "    return (word[0] == word[-1]) and palindrom_rec(word[1:len(word)-1])\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 30,
-   "id": "0c279628-9b96-4687-8e20-a954ab646e0f",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "True"
-      ]
-     },
-     "execution_count": 30,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "palindrom_rec(\"laval\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 31,
-   "id": "cf6fa61a-7c6f-4a32-96c2-b9fd50deacc6",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_annagram_rec",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert palindrom_rec(\"\")\n",
-    "assert palindrom_rec(\"AA\")\n",
-    "assert not palindrom_rec(\"ABC\")\n",
-    "assert palindrom_rec(\"ABA\")\n",
-    "assert palindrom_rec(\"LAVAL\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "798c2875-7940-488a-8458-ad08f6a71c70",
-   "metadata": {},
-   "source": [
-    "### Example 7: Calculate GCD\n",
-    "\n",
-    "_Here is the iterative way, write the recursive equivalent._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 32,
-   "id": "48c65c83-be0c-41c4-8c04-1d29ac4415cb",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def iterative_gcd(a, b):\n",
-    "    while b:\n",
-    "        a, b = b, a % b\n",
-    "    return a"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 33,
-   "id": "bf6e1a76",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "recursive_gcd",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def recursive_gcd(a, b):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if b == 0:\n",
-    "        return a\n",
-    "    else:\n",
-    "        return recursive_gcd(b, a % b)\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 34,
-   "id": "4f1feace",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "2"
-      ]
-     },
-     "execution_count": 34,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "recursive_gcd(10, 2)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 35,
-   "id": "e6ff1765-ff4b-49a5-80d3-684d2627e961",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_recursive_gcd",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert iterative_gcd(10, 2) == recursive_gcd(10, 2)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "d8b05edf-9536-4fc1-bfcc-ddbbeee426fc",
-   "metadata": {},
-   "source": [
-    "### Example 8: Check if a list of numbers is sorted"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 37,
-   "id": "1661dfb5-88f2-411f-8fe2-63bbaa29ce72",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "calculate_average_recursive",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def is_sorted(L):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if len(L) <= 1:\n",
-    "        return True\n",
-    "    else:\n",
-    "        return L[0] <= L[1] and is_sorted(L[1:])\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 33,
-   "id": "0c5c72c6-3237-4f98-ab96-50a1838b833f",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "True"
-      ]
-     },
-     "execution_count": 33,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "is_sorted([1, 2, 3, 4, 5])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 38,
-   "id": "9f18b6b7-d980-4a72-a2a8-3aa201003d21",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_calculate_average_recursive",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert is_sorted([2, 3])\n",
-    "assert is_sorted([])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "79eef392-1d3d-46c0-aeee-ac805686e6f1",
-   "metadata": {},
-   "source": [
-    "### Example 9: Check for prime number in a recursive function"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 40,
-   "id": "ac374a08-11c9-47e6-ba11-419549911266",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "is_prime_recursive",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def is_prime_recursive(n, divisor=2):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if n < 2:\n",
-    "        return False\n",
-    "    \n",
-    "    if n == 2:\n",
-    "        return True\n",
-    "    \n",
-    "    if n % divisor == 0:\n",
-    "        return False\n",
-    "    \n",
-    "    if divisor * divisor > n:\n",
-    "        return True\n",
-    "    \n",
-    "    return is_prime_recursive(n, divisor + 1)\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 41,
-   "id": "996fc91f",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "True"
-      ]
-     },
-     "execution_count": 41,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "is_prime_recursive(3)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 42,
-   "id": "5be1051c-3b60-4810-b855-6f8575ad6380",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_is_prime_recursive",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert is_prime_recursive(3) "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5423682d-c31f-4a8d-9a0f-6812de7b1ae3",
-   "metadata": {},
-   "source": [
-    "### Example 10: Count occurrences of a given element in a list"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 45,
-   "id": "cfeb0ad0-ed82-499e-9af3-64923291a0e7",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "count_occurrences",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def count_occurrences(L, target, index=0):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if index == len(L):\n",
-    "        return 0\n",
-    "    \n",
-    "    count = (1 if L[index] == target else 0)\n",
-    "    \n",
-    "    return count + count_occurrences(L, target, index + 1)\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 46,
-   "id": "49daec07-00b3-412e-ad44-5bafadbd9f36",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "4"
-      ]
-     },
-     "execution_count": 46,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "count_occurrences([1, 2, 3, 4, 2, 2, 5, 6, 2], 2)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 47,
-   "id": "14a2eb85-1126-4506-93bb-4bf624d046b6",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_count_occurrences",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert count_occurrences([1, 2, 3, 4, 2, 2, 5, 6, 2], 2) == 4"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "bb1784f5-2426-4661-aa13-dba96743ceb5",
-   "metadata": {},
-   "source": [
-    "# Bonus"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "7fdcd705-dc0b-4614-8e27-9ba62f8fe442",
-   "metadata": {},
-   "source": [
-    "### Exercise: Find the maximum value in a list (iterative)\n",
-    "\n",
-    "Check that an empty lists raises a `ValueError` exception with a `\"The list is empty.\"` message."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 41,
-   "id": "f9334f32-f760-46c0-a649-c82f267aba5b",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "try:\n",
-    "    result = find_maximum_iterative([])\n",
-    "    assert False, \"Exception not raised\"\n",
-    "except ValueError as e:\n",
-    "    assert str(e) == \"The list is empty.\", f\"Expected error message: 'The list is empty.' but got '{str(e)}'\""
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "c121315a-4aaa-4e04-912f-73f56555be56",
-   "metadata": {},
-   "source": [
-    "### Exercise: Find the maximum value in a list (recursive)\n",
-    "\n",
-    "Witout using the built-in `max` function"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 48,
-   "id": "153e3f05-7598-4920-bc8d-8943cb75e5a8",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# checks if a function uses another function, eg \"max\"\n",
-    "import inspect\n",
-    "\n",
-    "def calls_builtin_max(func):\n",
-    "    source_code = inspect.getsource(func)\n",
-    "    return 'max(' in source_code\n",
-    "\n",
-    "def my_function(lst):\n",
-    "    return max(lst)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 49,
-   "id": "775b7e32-a5ae-431b-9987-fcd3671fd022",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def find_maximum_recursive_no_max_func(L): \n",
-    "    if not L:\n",
-    "        raise ValueError(\"The list is empty.\")\n",
-    "    \n",
-    "    if len(L) == 1:\n",
-    "        return L[0]\n",
-    "    \n",
-    "    rest_max = find_maximum_recursive(L[1:])\n",
-    "    return L[0] if L[0] > rest_max else rest_max"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 50,
-   "id": "f76ed657-3288-4b36-9175-21168d2eb761",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert not calls_builtin_max(find_maximum_recursive_no_max_func)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "bbe7023a-aabd-489d-bae6-3b71566e22ef",
-   "metadata": {},
-   "source": [
-    "# Additional tests (do not change)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 51,
-   "id": "1c73ad0e-ddc9-483d-85a1-f2a65d04f30b",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert calls_builtin_max(my_function)\n",
-    "assert not calls_builtin_max(find_maximum_iterative)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 72,
-   "id": "8ce960f5-08da-449e-9e6f-dae215bc1b6a",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# generates more examples for a given function\n",
-    "def gen_examples(fnct, n=10):\n",
-    "    return [fnct(i) for i in range(0, n)]"
-   ]
-  }
- ],
- "metadata": {
-  "celltoolbar": "Slideshow",
-  "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/solutions/03-lists-search-sort-exercises.ipynb b/solutions/03-lists-search-sort-exercises.ipynb
deleted file mode 100644
index 1ea99e28b10d9dd9d9dda7b5ac88e7199ef21230..0000000000000000000000000000000000000000
--- a/solutions/03-lists-search-sort-exercises.ipynb
+++ /dev/null
@@ -1,685 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "e58599e3-9ab7-4d43-bb22-aeccade424ce",
-   "metadata": {},
-   "source": [
-    "# Lists, search, sort"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "691b3c38-0e83-4bb2-ac90-ef76d2dd9a7a",
-   "metadata": {},
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "id": "1095285f-26e2-43ce-a1c5-9358c5256a0b",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "list_complexities = [\"O(1)\", \"O(log(n))\", \"O(n)\", \"O(n^2)\", \"O(nlog(n))\", \"O(n^3)\", \"O(2^n)\", \"O(n!)\", \"O(n^n)\"]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "11a124a7-1279-469a-b091-2833d3fd1a0f",
-   "metadata": {},
-   "source": [
-    "## Exercise 0: Search the index first occurence of a target value\n",
-    "\n",
-    "_Write a Python function `search_list(L, v)` that takes a list `L` and a target element `v` as input. The function should return the index of the first occurrence of the target element in the list `L`._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "id": "665c7b64-428d-468a-860b-65d0d12e98e1",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def search_list(L, target):\n",
-    "    for n, i in enumerate(L):\n",
-    "        if i == target:\n",
-    "            return n\n",
-    "    return -1"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "id": "d776ca94-1ed2-4443-91e2-a1591a1690b8",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "1"
-      ]
-     },
-     "execution_count": 3,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "search_list([1, 2, 2], 2)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "id": "e7b5950c-a6f0-4795-995b-903d717f35c9",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert search_list([1, 2, 3, 4, 5], 3) == 2\n",
-    "assert search_list([1, 2, 3, 4, 5], 6) == -1\n",
-    "assert search_list([1, 2, 3, 4, 5], 6) == -1\n",
-    "assert search_list([], 42) == -1\n",
-    "assert search_list([7, 2, 3, 4, 5], 7) == 0\n",
-    "assert search_list([1, 2, 3, 4, 5, 6], 7) == -1"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "9d813205-b709-42ab-b414-6f3fc947022a",
-   "metadata": {},
-   "source": [
-    "## Exercise 1: Search in a list with an odd index\n",
-    "\n",
-    "_Write a Python function `search_list(L, v)` that takes a list `L` and a target element `v` as input. The function should return the index of the first occurrence of the target element in the list `L`._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "id": "f3b233ec-7077-479d-9c04-f1a4c35f3111",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "search_list",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def search_list(L, target):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    for i, element in enumerate(L):\n",
-    "        if element == target and i % 2 == 0:\n",
-    "            return i\n",
-    "    return -1\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "id": "f280eeea-4812-4a30-80b5-3fe1cafa9283",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "-1"
-      ]
-     },
-     "execution_count": 6,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "search_list([1, 2, 2], 3)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "id": "423d2637-8bd6-4e8f-95ff-2765dae5bce7",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_correct_search_list",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert search_list([1, 2, 3, 4, 5], 3) == 2\n",
-    "assert search_list([1, 2, 3, 4, 5], 6) == -1\n",
-    "assert search_list([1, 2, 3, 4, 5, 6], 6) == -1\n",
-    "assert search_list([], 42) == -1\n",
-    "assert search_list([7, 2, 3, 4, 5, 7], 7) == 0\n",
-    "assert search_list([1, 2, 3, 4, 5, 6], 6) == -1"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "6d8dc6cd-aad0-42a9-b768-6a1a5289e354",
-   "metadata": {},
-   "source": [
-    "## Exercise 2: Sort a list of tuples\n",
-    "\n",
-    "_Given a list of lists of length N, sort by the N-th element of the list._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "id": "8271ff47-efb4-48a0-ac4c-bba6ede7e578",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "sort_list_of_lists_by_nth_element",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sort_list_of_lists_by_nth_element(L_L, N):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    sorted_list = sorted(L_L, key=lambda x: x[N])\n",
-    "    return sorted_list\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "id": "4577bd24-9e50-4172-8246-d1bccfa21618",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "[[3, 5, 1], [2, 8, 3], [7, 4, 6], [1, 2, 9]]\n"
-     ]
-    }
-   ],
-   "source": [
-    "list_of_lists = [[3, 5, 1], [1, 2, 9], [7, 4, 6], [2, 8, 3]]\n",
-    "sorted_list = sort_list_of_lists_by_nth_element(list_of_lists, 2)\n",
-    "print(sorted_list)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "id": "ed3cdeed-07fa-461f-b7ae-210e1605ca76",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_sort_list_of_lists_by_nth_element",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "list1 = [[3, 5, 1], [1, 2, 9], [7, 4, 6], [2, 8, 3]]\n",
-    "sorted_list1 = sort_list_of_lists_by_nth_element(list1, 2)\n",
-    "assert sorted_list1 == [[3, 5, 1], [2, 8, 3], [7, 4, 6], [1, 2, 9]]\n",
-    "\n",
-    "list2 = [[9, 5, 7], [3, 6, 1], [0, 2, 4], [8, 1, 5]]\n",
-    "sorted_list2 = sort_list_of_lists_by_nth_element(list2, 0)\n",
-    "assert sorted_list2 == [[0, 2, 4], [3, 6, 1], [8, 1, 5], [9, 5, 7]]\n",
-    "\n",
-    "list3 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]\n",
-    "sorted_list3 = sort_list_of_lists_by_nth_element(list3, 1)\n",
-    "assert sorted_list3 == [[1, 2, 3], [4, 5, 6], [7, 8, 9]]\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "0bbda1ba-a5e7-4a1d-a742-84d0215b1e24",
-   "metadata": {},
-   "source": [
-    "## Exercise 3: Access a list element\n",
-    "\n",
-    "_Given an input list `L`, and `index` value, access a given `key` and return the value._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "id": "2d6a6f11-d24b-4f0e-a7d2-298243e35c4d",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-1ab0b636df63501a",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def access_dict_element(L, index, key):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if 0 <= index < len(L):\n",
-    "        if key in L[index]:\n",
-    "            return L[index][key]\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "id": "ea0883dc-d08c-40ea-9e0b-4f0a3abc517f",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Alice\n"
-     ]
-    }
-   ],
-   "source": [
-    "example_list = [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]\n",
-    "result = access_dict_element(example_list, 0, 'name')\n",
-    "print(result) "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "id": "88ae441e-58b1-4d6c-a639-530919658d03",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_access_dict_element",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "example_list = [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]\n",
-    "assert access_dict_element(example_list, 0, 'name') == 'Alice'\n",
-    "assert access_dict_element(example_list, 1, 'city') is None\n",
-    "assert access_dict_element(example_list, 2, 'name') is None\n",
-    "assert access_dict_element(example_list, 0, 'city') is None"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "98405b12-ad61-4007-8c9f-6955d238df41",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "## Exercise 4: Remove Elements from a List\n",
-    "\n",
-    "_Write a Python function `remove_elements(L, condition)` that takes a list `L` and a function `condition` as input._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 21,
-   "id": "e079e47b-2f9e-42d1-a78b-56c92ad84d63",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def is_odd(x):\n",
-    "    return x % 2 != 0"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 24,
-   "id": "536734bd-d4cc-4f83-8042-3c0e774c4034",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "remove_elements",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def remove_elements(L, condition):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    L[:] = [x for x in L if not condition(x)]\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 25,
-   "id": "a65bb6f1-b7c7-4156-ba8b-9b72a25616f3",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "[2, 4, 6, 8]\n"
-     ]
-    }
-   ],
-   "source": [
-    "my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
-    "remove_elements(my_list, is_odd)\n",
-    "print(my_list)  # Should print [2, 4, 6, 8]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 26,
-   "id": "254155dc-b271-4881-ac65-5a11d13990ea",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_remove_elements",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "test_list_1 = [12, 5, 18, 9, 25, 3, 15]\n",
-    "remove_elements(test_list_1, lambda x: x > 10)\n",
-    "assert test_list_1 == [5, 9, 3], \"Remove greater than 30\"\n",
-    "\n",
-    "test_list_2 = [-3, 7, -9, 2, 0, -1, 8]\n",
-    "remove_elements(test_list_2, lambda x: x < 0)\n",
-    "assert test_list_2 == [7, 2, 0, 8], \"Remove negative elements\"\n",
-    "\n",
-    "def custom_condition(x):\n",
-    "    return x % 3 == 0\n",
-    "test_list_3 = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
-    "remove_elements(test_list_3, custom_condition)\n",
-    "assert test_list_3 == [1, 2, 4, 5, 7, 8]\n",
-    "\n",
-    "test_list_4 = [42, 99, 101]\n",
-    "remove_elements(test_list_4, lambda x: True)\n",
-    "assert test_list_4 == [], \"Remove all elements\"\n",
-    "\n",
-    "test_list_5 = [10, 20, 30, 40]\n",
-    "remove_elements(test_list_5, lambda x: False)\n",
-    "assert test_list_5 == [10, 20, 30, 40], \"No element to remove\""
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "d75dba4b-ac22-4f2c-9a6c-cf333b1ec5e8",
-   "metadata": {},
-   "source": [
-    "## Exercise 5: Sort a dictionnary by values\n",
-    "\n",
-    "_Create a new sorted list as result._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 29,
-   "id": "556be9d8-b8c3-4f1d-bcb1-8f099968af9d",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "sort_dict_by_values",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sort_dict_by_values(input_dict):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    sorted_items = sorted(input_dict.items(), key=lambda item: item[1])\n",
-    "    sorted_dict = {}\n",
-    "    for key, value in sorted_items:\n",
-    "        sorted_dict[key] = value\n",
-    "    ### END SOLUTION\n",
-    "    return sorted_dict"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 30,
-   "id": "3c32c4ee-56f5-46b5-a8b6-b740e6d5fef5",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "test_dict3 = {'c': 3, 'b': 2, 'a': 1}\n",
-    "sorted_dict3 = sort_dict_by_values(test_dict3)\n",
-    "assert sorted_dict3 == {'a': 1, 'b': 2, 'c': 3}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 31,
-   "id": "532e5225-a2d8-4c10-a036-1efde9acc5fd",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_sort_dict_by_values",
-     "locked": true,
-     "points": 0,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "test_dict = {'banana': 3, 'apple': 1, 'cherry': 2}\n",
-    "sorted_dict = sort_dict_by_values(test_dict)\n",
-    "assert sorted_dict == {'apple': 1, 'cherry': 2, 'banana': 3}\n",
-    "\n",
-    "test_dict2 = {'zebra': 42, 'lion': 7, 'elephant': 15, 'giraffe': 23}\n",
-    "sorted_dict2 = sort_dict_by_values(test_dict2)\n",
-    "assert sorted_dict2 == {'lion': 7, 'elephant': 15, 'giraffe': 23, 'zebra': 42}\n",
-    "\n",
-    "test_dict3 = {'one': 3, 'two': 3, 'three': 3, 'four': 3}\n",
-    "sorted_dict3 = sort_dict_by_values(test_dict3)\n",
-    "assert sorted_dict3 == {'one': 3, 'two': 3, 'three': 3, 'four': 3}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "fef2ad7f-55ef-43f2-991d-5067bb085eb6",
-   "metadata": {},
-   "source": [
-    "## Exercise 6: insertion sort\n",
-    "\n",
-    "Implement the `insertion sort` that operates as follows:\n",
-    "\n",
-    "- Start with an unsorted list.\n",
-    "- Iterate through each element in the list.\n",
-    "- For each element, compare it with the elements to its left in the list.\n",
-    "- Move elements to the right until you find the correct position for the current element.\n",
-    "- Insert the current element into its proper place in the sorted portion of the list.\n",
-    "- Repeat this process for all elements, gradually building a sorted list from left to right."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 32,
-   "id": "51a86852-f8e2-4c05-8053-13fdf2a4832b",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "insertion_sort",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def insertion_sort(arr):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    for i in range(1, len(arr)):\n",
-    "        key = arr[i]\n",
-    "        j = i - 1\n",
-    "        while j >= 0 and key < arr[j]:\n",
-    "            arr[j + 1] = arr[j]\n",
-    "            j -= 1\n",
-    "        arr[j + 1] = key\n",
-    "    return arr\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 33,
-   "id": "fbfa74f1-4675-452f-897b-21b0c7025f81",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "[1, 2, 3, 4, 5]\n"
-     ]
-    }
-   ],
-   "source": [
-    "print(insertion_sort([2, 1, 3, 4, 5]))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 35,
-   "id": "266e89e0-4b59-441f-bb67-69ad4e35e2a9",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_insertion_sort",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# Test case 2: Already sorted list\n",
-    "arr = [1, 2, 3, 4, 5]\n",
-    "assert insertion_sort(arr) == arr\n",
-    "\n",
-    "# Test case 3: Reverse sorted list\n",
-    "arr = [5, 4, 3, 2, 1]\n",
-    "assert insertion_sort(arr) == [1, 2, 3, 4, 5]\n",
-    "\n",
-    "# Test case 4: Random order list\n",
-    "arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]\n",
-    "assert insertion_sort(arr) == [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "ab78dd44-bb6a-451d-8642-223639d31bf9",
-   "metadata": {},
-   "source": [
-    "## Bonus\n",
-    "\n",
-    "Extra tasks:\n",
-    "\n",
-    "- add exceptions https://docs.python.org/3/library/exceptions.html\n",
-    "- add more test cases"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "d7622873-8c3b-496a-977c-5413309653e3",
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/solutions/04-05-06-programming-strategies-exercises.ipynb b/solutions/04-05-06-programming-strategies-exercises.ipynb
deleted file mode 100644
index 7f1057d927890e0ee4aadb663a1e354c647b7f51..0000000000000000000000000000000000000000
--- a/solutions/04-05-06-programming-strategies-exercises.ipynb
+++ /dev/null
@@ -1,1052 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "e58599e3-9ab7-4d43-bb22-aeccade424ce",
-   "metadata": {},
-   "source": [
-    "# Programming strategies"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "691b3c38-0e83-4bb2-ac90-ef76d2dd9a7a",
-   "metadata": {},
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "9d813205-b709-42ab-b414-6f3fc947022a",
-   "metadata": {},
-   "source": [
-    "## Exercise 1: tribonacci\n",
-    "\n",
-    "Here is an implementation of the Tribonacci sequence (similar to the Fibonacci) defined as:\n",
-    "\n",
-    "$T(n) = T(n-1) + T(n-2) + T(n-3)$\n",
-    "\n",
-    "_Explain the role of the `tab` variable; write some tests._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "id": "f3b233ec-7077-479d-9c04-f1a4c35f3111",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def tribonacci(n: int) -> int:\n",
-    "        \n",
-    "        if(n==0):\n",
-    "            return 0\n",
-    "        if(n==1):\n",
-    "            return 1\n",
-    "        if(n==2):\n",
-    "            return 1\n",
-    "        \n",
-    "        tab=[0 for i in range(n+1)]\n",
-    "        tab[0]=0\n",
-    "        tab[1]=1\n",
-    "        tab[2]=1\n",
-    "        \n",
-    "        for i in range(3, n+1):\n",
-    "            tab[i]=tab[i-1]+tab[i-2]+tab[i-3]\n",
-    "        \n",
-    "        return tab[n]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "id": "f280eeea-4812-4a30-80b5-3fe1cafa9283",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "274"
-      ]
-     },
-     "execution_count": 2,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "tribonacci(11)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "id": "423d2637-8bd6-4e8f-95ff-2765dae5bce7",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-9e7356aa23ccfb4c",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "### BEGIN SOLUTION\n",
-    "assert tribonacci(0) == 0\n",
-    "assert tribonacci(1) == 1\n",
-    "assert tribonacci(2) == 1\n",
-    "assert tribonacci(11) == 274\n",
-    "### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "b2b31dca-a19a-46cf-b0de-4feec6afa083",
-   "metadata": {},
-   "source": [
-    "## Exercice 2: find two numbers with a given sum\n",
-    "\n",
-    "_Find two numbers in an array `nums` that add up to a specific target value `target`. Return a list of the values index._ \n",
-    "\n",
-    "_Tip: make sure you do not use twice the same array element._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "id": "f5a964df-958e-4758-8ca2-1139c59a7585",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "two_sum",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def two_sum(nums, target: int):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    for i in range(len(nums) - 1):\n",
-    "        for j in range(i + 1, len(nums)):\n",
-    "            if(nums[i] + nums[j] == target):\n",
-    "                return([i, j])\n",
-    "    return -1\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "id": "1cec37b0-5d27-4973-b53a-053a46992c0c",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "[0, 2]"
-      ]
-     },
-     "execution_count": 5,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "two_sum([1, 2, 3, 4, 5], 4)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "id": "395cb69f-b99a-4c60-88f5-11216a5ec857",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_two_sum",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert two_sum([2, 7, 11, 15, 19], 9) == [0, 1]  # 2 + 7 = 9\n",
-    "assert two_sum([3, 2, 4], 6) == [1, 2]       # 2 + 4 = 6\n",
-    "assert two_sum([3, 3], 6) == [0, 1]          # 3 + 3 = 6\n",
-    "assert two_sum([3, 3], 123) == -1            # not possible"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "dc4f4361-5dee-4e19-b3fd-d18ea40d341e",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "## Exercice 3: find the minimum distance between two points\n",
-    "\n",
-    "_Given a list of points find the minimum distance between all the pairs of points._\n",
-    "\n",
-    "- write a `dist`function using \n",
-    "- define a `closest_point_naive`function using `math.inf`as initial value\n",
-    "\n",
-    "Tip: make sure you do not use the same point twice!"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "id": "f73f28a4-d39c-497d-9cbb-1c4edd1c628f",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import math"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "id": "0be305c3-c054-4092-b041-bd7e705e2178",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-8738237c4c6682e4",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def dist(point1, point2):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    return math.sqrt((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2)\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "id": "c0e25948-eefd-4cb0-a893-c3d5e34ff0ee",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-9ca280911ed42034",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def closest_point_naive(P):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    min_dist = math.inf\n",
-    "    n = len(P)\n",
-    "    for i in range(n):\n",
-    "        for j in range(i + 1, n):\n",
-    "            if dist(P[i], P[j]) < min_dist:\n",
-    "                min_dist = dist(P[i], P[j])\n",
-    "    return min_dist\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "id": "965d8274-470e-4a3e-8b88-60d458de74e2",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "1.4142135623730951"
-      ]
-     },
-     "execution_count": 10,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "points = [(1, 2), (4, 6), (7, 8), (3, 5)]\n",
-    "closest_point_naive(points)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "id": "5d875175-45c3-4594-a434-23e15cfb88f7",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "cell-618f956021833284",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.0"
-      ]
-     },
-     "execution_count": 11,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "points1 = [(1, 2), (4, 6), (0, 0), (0, 0)]\n",
-    "closest_point_naive(points1)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "id": "755116cb-456e-48ad-8dfe-bd72617488d9",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert math.isclose(closest_point_naive(points1), 0.0, rel_tol=1e-9)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "4d521622-f4b7-4859-b501-2583b943d0e7",
-   "metadata": {},
-   "source": [
-    "## Exercice 4: display the minimum distance\n",
-    "\n",
-    "_Update the previous function to take a single list of points `P`as input and return the closest points and draw the line that connects them._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "id": "a5902565-9c98-482a-8e63-9cc37214beb2",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from matplotlib import pyplot as plt\n",
-    "import random\n",
-    "\n",
-    "points_count = 10\n",
-    "x = [random.gauss(0, 1) for _ in range(points_count)]\n",
-    "y = [random.gauss(0, 1) for _ in range(points_count)]\n",
-    "\n",
-    "def draw_points(x, y):\n",
-    "    color = \"blue\"\n",
-    "    plt.figure(figsize=(10, 7))\n",
-    "    _ = plt.plot(x, y, '.', markersize=14, color=color)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "id": "e35557a8-54cb-4324-b280-4479835685db",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/png": "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",
-      "text/plain": [
-       "<Figure size 1000x700 with 1 Axes>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "draw_points(x, y)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "id": "6c504c53-d3fc-44a1-904c-49ceff572638",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "closest_point_naive_pair",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def closest_point_naive_pair(P):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    n = len(P)\n",
-    "    min_dist = math.inf\n",
-    "    closest_point1 = None\n",
-    "    closest_point2 = None\n",
-    "\n",
-    "    for i in range(n):\n",
-    "        for j in range(i + 1, n):\n",
-    "            distance = dist(P[i], P[j])\n",
-    "            if distance < min_dist:\n",
-    "                min_dist = distance\n",
-    "                closest_point1 = P[i]\n",
-    "                closest_point2 = P[j]\n",
-    "\n",
-    "    ### END SOLUTION\n",
-    "    return closest_point1, closest_point2"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "id": "4266685c-19f9-4d2f-bb71-4d047bb54787",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_closest_point_naive_pair",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/png": "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F//e3XffnRUrVuSjH/1otmzZkksuuSQLFy7Mjh07Djv+6aefzhVXXJFLLrkkW7ZsyUc+8pFcf/31Wbdu3TDPnNFgsPvXy5588skB31NveMMbhmnGjFl1BuWOO+6ot7e3H9fYpUuX1t/1rnc1dD6MLce7f/X19dVnzJhR/6u/+qv+db/+9a/r7e3t9VtvvbWBM2Q0+ad/+qd6kvrjjz/ev27jxo31JPUnnnjiiNv57uKV3vjGN9aXL18+YN0555xT//CHP3zY8X/2Z39WP+eccwas+8M//MP6vHnzGjZHRq/B7l8PPfRQPUn9F7/4xTDMjpI4YtRgGzZsyLRp03L22Wfnuuuuy3PPPdfsKTEGPP3009m9e3cWLFjQv661tTVvfetb89hjjzVxZowkGzduTHt7e970pjf1r5s3b17a29uPuZ/47uJl+/fvz+bNmwd83yTJggULjrgfbdy48ZDxl112WTZt2pSXXnqpYXNl9DmR/etlF1xwQWbOnJlLL700Dz30UCOnSSGEUQMtXLgwd955Z77zne/k05/+dL7//e/n7W9/e3p6epo9NUa53bt3J0mmT58+YP306dP7P4Pdu3dn2rRph6yfNm3aUfcT3138e3v27MmBAwcG9X2ze/fuw47v7e3Nnj17GjZXRp8T2b9mzpyZ2267LevWrcvXvva1zJkzJ5deemkeeeSR4ZgyY1jRYXTTTTcd9uK9f//atGnTCf/5V111Va688sqcf/75WbRoUb71rW/lxz/+ce67774h/C0YqRq9fyVJrVYbsFyv1w9Zx9gzmH3rcPvDsfYT310czmC/bw43/nDrIRnc/jVnzpxcd911ufDCCzN//vzccsstufLKK/OpT31qOKbKGNbS7Ak004c+9KG8//3vP+qYM888c8h+3syZM3PGGWfkqaeeGrI/k5GrkfvXjBkzklT/Kjtz5sz+9c8999wh/+rG2HO8+9YPfvCD/OxnPzvks5///OeD2k98d5Vt6tSpGT9+/CH/en+075sZM2YcdnxLS0te85rXNGyujD4nsn8dzrx587J27dqhnh6FKTqMpk6dmqlTpw7bz3v++eezc+fOAX+RZexq5P511llnZcaMGVm/fn0uuOCCJNV52g8//HA++clPNuRnMnIc7741f/78dHV15Xvf+17e+MY3Jkm++93vpqurKxdffPFx/zzfXWWbMGFCOjo6sn79+rznPe/pX79+/fq8613vOuw28+fPzze/+c0B6x588MFcdNFFOeWUUxo6X0aXE9m/DmfLli2+ozhpRZ9KNxg7duzI1q1bs2PHjhw4cCBbt27N1q1b8+KLL/aPOeecc3LPPfckSV588cWsWrUqGzduzE9+8pNs2LAhixYtytSpUwf8jw/J4PevWq2WFStW5BOf+ETuueee/OM//mOuvfbaTJ48OVdffXWzfg1GmHPPPTeXX355rrvuujz++ON5/PHHc9111+Wd73xn5syZ0z/OdxfHsnLlynzxi1/M7bffnu3bt+eGG27Ijh07snz58iTJjTfemGuuuaZ//PLly/PTn/40K1euzPbt23P77bfnS1/6UlatWtWsX4ERbLD71+rVq3Pvvffmqaeeyo9+9KPceOONWbduXT70oQ8161dgrGjqPfFGkaVLl9aTHPJ66KGH+sckqd9xxx31er1e/9WvflVfsGBB/bWvfW39lFNOqZ9++un1pUuX1nfs2NGcX4ARbbD7V71e3bL7Yx/7WH3GjBn11tbW+lve8pb6D3/4w+GfPCPa888/X//ABz5QnzJlSn3KlCn1D3zgA4fc4tZ3F8fj85//fP2MM86oT5gwoX7hhRfWH3744f7Pli5dWn/rW986YPyGDRvqF1xwQX3ChAn1M888s/6FL3xhmGfMaDKY/euTn/xk/Td/8zfrEydOrP/Gb/xG/c1vfnP9vvvua8KsGWtq9fq/XQ0JAABQKKfSAQAAxRNGAABA8YQRAABQPGEEAAAUTxgBAADFE0YAAEDxhBEAAFA8YQQAABRPGAEAAMUTRgAAQPGEEQAAULz/H0TsW122D28CAAAAAElFTkSuQmCC",
-      "text/plain": [
-       "<Figure size 1000x700 with 1 Axes>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "from matplotlib import pyplot as plt\n",
-    "import random\n",
-    "import math\n",
-    "\n",
-    "points_count = 10\n",
-    "color = \"blue\"\n",
-    "x = [random.gauss(0, 1) for _ in range(points_count)]\n",
-    "y = [random.gauss(0, 1) for _ in range(points_count)]\n",
-    "\n",
-    "points = list(zip(x, y))\n",
-    "\n",
-    "closest_point1, closest_point2 = closest_point_naive_pair(points)\n",
-    "\n",
-    "plt.figure(figsize=(10, 7))\n",
-    "_ = plt.plot(x, y, '.', markersize=14, color=color)\n",
-    "plt.plot([closest_point1[0], closest_point2[0]], [closest_point1[1], closest_point2[1]], '-', color='red', linewidth=2)\n",
-    "\n",
-    "plt.show()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 103,
-   "id": "bcec1dfc-6ce9-4b08-bc1c-f8d0887aa876",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "((0, 0), (1, 1))"
-      ]
-     },
-     "execution_count": 103,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "points1 = [(0, 0), (1, 1), (3, 3), (5, 5)]\n",
-    "closest_point_naive_pair(points1)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 104,
-   "id": "aad82edd-144d-4117-9ee6-485b9e739251",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert closest_point_naive_pair(points1) == ((0, 0), (1, 1))"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "52ede988-1834-489d-9cca-e9882e90f9af",
-   "metadata": {},
-   "source": [
-    "## Exercice 5: implement the merge sort\n",
-    "\n",
-    "0. Find a base case\n",
-    "1. Finding the mid of the array \n",
-    "2. Divide the array elements  into 2 halves \n",
-    "3. Sorting the first half and the second half independantly\n",
-    "4. merge by copying arrays into a final one"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 24,
-   "id": "b835049a-27a7-4d45-b819-b9e4d813fdcf",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "merge_sort",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def merge_sort(L):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if len(L) > 1:\n",
-    "        mid = len(L) // 2\n",
-    "        left_half = L[:mid]\n",
-    "        right_half = L[mid:]\n",
-    "\n",
-    "        merge_sort(left_half)\n",
-    "        merge_sort(right_half)\n",
-    "\n",
-    "        i = j = k = 0\n",
-    "\n",
-    "        while i < len(left_half) and j < len(right_half):\n",
-    "            if left_half[i] < right_half[j]:\n",
-    "                L[k] = left_half[i]\n",
-    "                i += 1\n",
-    "            else:\n",
-    "                L[k] = right_half[j]\n",
-    "                j += 1\n",
-    "            k += 1\n",
-    "\n",
-    "        while i < len(left_half):\n",
-    "            L[k] = left_half[i]\n",
-    "            i += 1\n",
-    "            k += 1\n",
-    "\n",
-    "        while j < len(right_half):\n",
-    "            L[k] = right_half[j]\n",
-    "            j += 1\n",
-    "            k += 1\n",
-    "\n",
-    "    return L\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 25,
-   "id": "4ad36fe3-7e9e-4ae8-9df6-f816e24d6c28",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "[1, 3, 6]"
-      ]
-     },
-     "execution_count": 25,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "merge_sort([3, 6, 1])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 26,
-   "id": "85865859-828f-4a6b-aad8-51ba0de8ac5b",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_merge_sort",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert merge_sort([4, 2, 3]) == sorted([4, 2, 3])\n",
-    "assert merge_sort([7, 2, 1]) == [1, 2, 7]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e5b7304d-7b64-42df-9465-8f4491525a8b",
-   "metadata": {},
-   "source": [
-    "# Exercice 6: organize a schedule\n",
-    "\n",
-    "_Propose a greedy algorithm that returns a list of time slots that do not overlap._\n",
-    "\n",
-    "In this question you may prioritize the ones that end last, so you may sort by [reverse order](https://docs.python.org/3/howto/sorting.html)."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 50,
-   "id": "e0ed0841-1255-4bdb-b7f8-e689c2a953af",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "interval_scheduling",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def interval_scheduling(intervals):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if not intervals:\n",
-    "        return []\n",
-    "\n",
-    "    intervals.sort(key=lambda x: x[1])\n",
-    "    \n",
-    "    selected_intervals = [intervals[0]]\n",
-    "    current_end_time = intervals[0][1]\n",
-    "    \n",
-    "    for interval in intervals[1:]:\n",
-    "        start_time, end_time = interval\n",
-    "        if start_time >= current_end_time:\n",
-    "            selected_intervals.append(interval)\n",
-    "            current_end_time = end_time\n",
-    "\n",
-    "    return selected_intervals\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 51,
-   "id": "d6a50280-f016-4686-8515-1b4a136c0fd9",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "[(0, 2), (2, 4)]"
-      ]
-     },
-     "execution_count": 51,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "interval_scheduling([(0, 2), (2, 4), (1, 3)])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 52,
-   "id": "bd38d673-077d-44b1-b81c-ac7448f5c01c",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_interval_scheduling",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert interval_scheduling([(0, 2), (2, 4), (1, 3)]) == [(0, 2), (2, 4)]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 53,
-   "id": "de2c9857-9925-4477-96e4-341fa5bc4ec8",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert interval_scheduling([(0, 2), (2, 4), (1,3)]) == [(0, 2), (2, 4)]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "c142c3b3-2f01-48d0-8596-601bb133542b",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "Now you may prioritize the ones that are the longest."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 54,
-   "id": "095836b8-2612-4d58-a9ce-b7968489418c",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "interval_scheduling_longest",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def interval_scheduling_longest(intervals):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    intervals.sort(key=lambda x: x[1] - x[0], reverse=True)\n",
-    "    \n",
-    "    selected_intervals = []\n",
-    "    current_end_time = float('-inf')\n",
-    "    \n",
-    "    for interval in intervals:\n",
-    "        start_time, end_time = interval\n",
-    "        if start_time >= current_end_time:\n",
-    "            selected_intervals.append(interval)\n",
-    "            current_end_time = end_time\n",
-    "    return selected_intervals\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 55,
-   "id": "c87ae1e2-7497-4920-9597-d1b3cddf8580",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "[(0, 4), (5, 7)]"
-      ]
-     },
-     "execution_count": 55,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "interval_scheduling_longest([(0, 4), (3, 5), (5, 7)])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 56,
-   "id": "afcf3a69-aa36-4b71-93a8-218337ed88b9",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_interval_scheduling_longest",
-     "locked": true,
-     "points": 1,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert interval_scheduling_longest([(0, 4), (3, 5), (5, 7)]) == [(0, 4), (5, 7)]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a559e4db-9ef2-4d20-bb9f-cb638d8c1f24",
-   "metadata": {},
-   "source": [
-    "# Exercice 7: knapsack problem\n",
-    "\n",
-    "Propose a greedy solution for the Kanpsack problem defined as follows:\n",
-    "\n",
-    "$\\sum_{i=1}^n w_i x_i \\leq W$ and $x_i \\in \\{0,1,2,\\dots,c\\}$\n",
-    "\n",
-    "Which selects the item with the least weight that can fit within the knapsack's capacity at each step "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5833bde3-1960-43ad-b140-381ac6dd228c",
-   "metadata": {},
-   "source": [
-    "`W:` The maximum weight capacity of the knapsack.\n",
-    "\n",
-    "`w:` A list of item weights.\n",
-    "\n",
-    "`n:` The number of items available to choose from.\n",
-    "\n",
-    "Tip:\n",
-    "\n",
-    "- Initialize with all the item indices of the remaining items\n",
-    "- Start with an empty knapsack of total weight 0\n",
-    "- Create a loop that selects the best item from the remaining (with least weight)\n",
-    "- Add the item to the knapsack and remove it from the list of items\n",
-    "- Return the total weight and list of items used"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 57,
-   "id": "46947633-3f5f-420b-b416-500a0dab4fcb",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-0bf75b2bfe8e2e4c",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def greedy_knapsack(W, w):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    w.sort(reverse=True)\n",
-    "    n = len(w)\n",
-    "    remaining_items = list(range(n))\n",
-    "\n",
-    "    total_weight = 0\n",
-    "    knapsack = []\n",
-    "\n",
-    "    while remaining_items and total_weight < W:\n",
-    "        best_weight = float('inf')\n",
-    "        best_item = None\n",
-    "\n",
-    "        for i in remaining_items:\n",
-    "            if w[i] < best_weight:\n",
-    "                best_weight = w[i]\n",
-    "                best_item = i\n",
-    "\n",
-    "        if best_item is not None:\n",
-    "            weight = w[best_item]\n",
-    "            knapsack.append(weight)\n",
-    "            total_weight += weight\n",
-    "            remaining_items.remove(best_item)\n",
-    "\n",
-    "    return total_weight, knapsack\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 58,
-   "id": "737df134-4ee1-49a9-9034-da3b0267ae84",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Total weight: 5 and selected weights: [2, 3]\n"
-     ]
-    }
-   ],
-   "source": [
-    "weights = [5, 3, 4, 2]\n",
-    "max_weight = 5\n",
-    "\n",
-    "result, selected_weights = greedy_knapsack(max_weight, weights)\n",
-    "print(\"Total weight:\", result, \"and selected weights:\", selected_weights)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 59,
-   "id": "a66c6e52-2d60-4423-bc3a-a3dcef38da26",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert greedy_knapsack(5, [2, 3, 4, 5]) == (5, [2, 3])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "37ff64e9-fc2c-4593-b85a-d83982445b9d",
-   "metadata": {},
-   "source": [
-    "Propose a dynamic programming solution following the general case:\n",
-    "\n",
-    "$\n",
-    "dp[i][w] = \n",
-    "\\begin{cases}\n",
-    "0 & \\text{if } i = 0 \\text{ or } w = 0 \\\\\n",
-    "dp[i-1][w] & \\text{if } w_i > w \\\\\n",
-    "\\max(dp[i-1][w], w_i + dp[i-1][w - w_i]) & \\text{otherwise}\n",
-    "\\end{cases}$"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 60,
-   "id": "2be5f2f7-d9a5-4cf0-afe4-5a5a54ee0434",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-5dc5571a7aca5b0f",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def dynamic_knapsack(W, wt):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    n = len(wt)\n",
-    "\n",
-    "    dp = [[0 for _ in range(W + 1)] for _ in range(n + 1)]\n",
-    "\n",
-    "    for i in range(n + 1):\n",
-    "        for w in range(W + 1):\n",
-    "            if i == 0 or w == 0:\n",
-    "                dp[i][w] = 0\n",
-    "            elif wt[i - 1] <= w:\n",
-    "                dp[i][w] = max(wt[i - 1] + dp[i - 1][w - wt[i - 1]], dp[i - 1][w])\n",
-    "            else:\n",
-    "                dp[i][w] = dp[i - 1][w]\n",
-    "\n",
-    "    max_weight = dp[n][W]\n",
-    "\n",
-    "    selected_items = []\n",
-    "    w = W\n",
-    "    for i in range(n, 0, -1):\n",
-    "        if dp[i][w] != dp[i - 1][w]:\n",
-    "            selected_items.append(wt[i - 1])\n",
-    "            w -= wt[i - 1]\n",
-    "\n",
-    "    return max_weight, selected_items\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 61,
-   "id": "5adf0e0e-73c4-4656-b546-5b02347f1a28",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Total weight: 5 and selected weights: [3, 2]\n"
-     ]
-    }
-   ],
-   "source": [
-    "weights = [2, 3, 4, 5]\n",
-    "max_weight = 5\n",
-    "result, selected_weights = dynamic_knapsack(max_weight, weights)\n",
-    "print(\"Total weight:\", result, \"and selected weights:\", selected_weights)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ef20e870-fcba-4610-bf22-37af0b0691a0",
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/solutions/07-stacks-queues-exercises.ipynb b/solutions/07-stacks-queues-exercises.ipynb
deleted file mode 100644
index adc6ca745daa7fd7919295371d1c8da5c5260d0d..0000000000000000000000000000000000000000
--- a/solutions/07-stacks-queues-exercises.ipynb
+++ /dev/null
@@ -1,479 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "2f1f2dcd-96a9-45ef-90a6-4ad488635679",
-   "metadata": {},
-   "source": [
-    "# Stacks and queues"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "b9bd540c-dd15-49ac-bfbd-f2e758688a85",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "03a0653e-65c2-4e79-9e83-31765cf19098",
-   "metadata": {},
-   "source": [
-    "## Exercise 1: Reverse a string using a Stack\n",
-    "\n",
-    "_Use the `Stack` below to reverse a string given as input._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "id": "4932473d-2734-4e81-b777-ca10decfd9e8",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class Stack:\n",
-    "    def __init__(self):\n",
-    "        self.items = []\n",
-    "\n",
-    "    def push(self, item):\n",
-    "        self.items.append(item)\n",
-    "\n",
-    "    def pop(self):\n",
-    "        if not self.is_empty():\n",
-    "            return self.items.pop()\n",
-    "\n",
-    "    def peek(self):\n",
-    "        if not self.is_empty():\n",
-    "            return self.items[-1]\n",
-    "\n",
-    "    def is_empty(self):\n",
-    "        return len(self.items) == 0"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "id": "8b77ae34-ef7c-4664-94e0-8928156f2224",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-5b0828e97507162e",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def reverse_string(s):\n",
-    "    ### BEGIN SOLUTION ###\n",
-    "    stack = Stack()\n",
-    "    reversed_string = \"\"\n",
-    "\n",
-    "    for char in s: # push char in the stack\n",
-    "        stack.push(char)\n",
-    "\n",
-    "    while not stack.is_empty(): # pop from the stack\n",
-    "        reversed_string += stack.pop()\n",
-    "\n",
-    "    return reversed_string\n",
-    "    ### END SOLUTION ###"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "id": "63719c8e-f60c-4544-8e41-cb6380ae4bcf",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'olleH'"
-      ]
-     },
-     "execution_count": 3,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "reverse_string(\"Hello\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "id": "81e93620-0664-4a9d-ba5f-894937c9769e",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert reverse_string(\"Hello\") == \"olleH\" "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "81df9b1e-cfe5-4b69-96a5-c8065259cc7d",
-   "metadata": {},
-   "source": [
-    "## Exercise 2: Check if a word is a palindrom (using a Stack)\n",
-    "_A palindrome is a sequence of characters that reads the same forward and backward._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "id": "cf6fbdd5-53c5-45c2-a0c5-a5ed845c4f81",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "is_palindrome",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def is_palindrome(s):\n",
-    "    ### BEGIN SOLUTION ###\n",
-    "    return s == reverse_string(s)\n",
-    "    ### END SOLUTION ###"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "id": "586bafba-2fbb-4833-b2e3-609db9b28fbf",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "True"
-      ]
-     },
-     "execution_count": 6,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "is_palindrome(\"ABA\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "id": "d0005a10-9152-4aa5-a94b-fcbff1bd2281",
-   "metadata": {
-    "nbgrader": {
-     "grade": true,
-     "grade_id": "correct_is_palindrome",
-     "locked": true,
-     "points": 0,
-     "schema_version": 3,
-     "solution": false,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert is_palindrome(\"ABA\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "f767bf25-9f4f-4a0d-8cb9-b729bbec5c27",
-   "metadata": {},
-   "source": [
-    "## Exercise 3: Implement a min-heap\n",
-    "\n",
-    "Use a `PriorityQueue` to return the smallest element when using `pop` of a stack (or a queue). "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "id": "ddcccaf6-d235-4327-826f-7a62a4c23f28",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from queue import PriorityQueue"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "id": "2da2db1e-f55d-43b4-877f-96ef944818e8",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "(1, 'banana')\n"
-     ]
-    }
-   ],
-   "source": [
-    "# how to use the queue module\n",
-    "priority_queue = PriorityQueue()\n",
-    "priority_queue.put((3, 'apple'))\n",
-    "priority_queue.put((1, 'banana'))\n",
-    "priority_queue.put((2, 'cherry'))\n",
-    "element = priority_queue.get()\n",
-    "print(element)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "id": "804ea32d-5bf8-42b9-ae52-6318b26f4065",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-4b9a5ecdee87514e",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "### BEGIN SOLUTION ###\n",
-    "class MinHeap:\n",
-    "    def __init__(self):\n",
-    "        self.heap = PriorityQueue()\n",
-    "\n",
-    "    def insert(self, value):\n",
-    "        self.heap.put(value)\n",
-    "\n",
-    "    def pop(self):\n",
-    "        if not self.is_empty():\n",
-    "            return self.heap.get()\n",
-    "\n",
-    "    def peek(self):\n",
-    "        if not self.is_empty():\n",
-    "            return self.heap.queue[0]\n",
-    "\n",
-    "    def is_empty(self):\n",
-    "        return self.heap.empty()\n",
-    "### END SOLUTION ###"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "id": "1b2d28c4-277b-44fa-b7e8-590aa00f8f70",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "min_heap = MinHeap()\n",
-    "min_heap.insert(5)\n",
-    "min_heap.insert(3)\n",
-    "min_heap.insert(8)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "id": "ed61bced-f000-41c6-8ecd-d669b4edb700",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert min_heap.pop() == 3\n",
-    "assert min_heap.peek() == 5\n",
-    "assert min_heap.peek() == 5"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a445d290-b04f-49b5-a8e7-2c6e259daf58",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "## Exercise 4: Evaluate a postfix expression\n",
-    "\n",
-    "_Write a code that given the following expression, provides the following evaluation (using arthmetic operations over numerical values)._\n",
-    "\n",
-    "Expression: `\"3 4 +\"`\n",
-    "Evaluation: `3 + 4 = 7`\n",
-    "\n",
-    "First step: write a function `apply_operator` that applies an operation (ie + - * /) over two elements."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "id": "4cc7f805-0887-4422-b6b7-3d591d0df1fb",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-8c5106f02f243455",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def apply_operator(op, b, a):\n",
-    "### BEGIN SOLUTION ###\n",
-    "    if op == '+':\n",
-    "        return a + b\n",
-    "    elif op == '-':\n",
-    "        return a - b\n",
-    "    elif op == '*':\n",
-    "        return a * b\n",
-    "    elif op == '/':\n",
-    "        return a / b\n",
-    "### END SOLUTION ###"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e68bdf7c-ca08-4553-9874-8bd9038fd4b5",
-   "metadata": {},
-   "source": [
-    "Solution in pseudo-code:\n",
-    "- Split the input expression in to a list of tokens\n",
-    "- If not an operator\n",
-    "    - Add the value to the stack\n",
-    "- If an operator \n",
-    "    - Make sure there is enough parameters `a` and `b`\n",
-    "    - Pop `a` and `b`\n",
-    "    - Apply `apply_operator` on `a` and `b`\n",
-    "    - Store the result in the stack"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "id": "e792c90d-1b38-47f5-9879-399debc934b9",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-e9236618b265b34f",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def evaluate_postfix(expression):\n",
-    "### BEGIN SOLUTION ###\n",
-    "    stack = []\n",
-    "    operators = set(['+', '-', '*', '/'])\n",
-    "\n",
-    "    tokens = expression.split()\n",
-    "    \n",
-    "    for token in tokens:\n",
-    "        if token not in operators:\n",
-    "            stack.append(float(token))\n",
-    "        else:\n",
-    "            if len(stack) < 2:\n",
-    "                raise ValueError(\"Invalid expression\")\n",
-    "            b = stack.pop()\n",
-    "            a = stack.pop()\n",
-    "            result = apply_operator(token, b, a)\n",
-    "            stack.append(result)\n",
-    "\n",
-    "    if len(stack) != 1:\n",
-    "        raise ValueError(\"Invalid expression\")\n",
-    "\n",
-    "    return stack[0]\n",
-    "### END SOLUTION ###"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 17,
-   "id": "ea6e4840-1b7e-4265-b37d-e8c45ea6b3ed",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "14.0\n"
-     ]
-    }
-   ],
-   "source": [
-    "postfix_expression = \"3 4 + 2 *\"\n",
-    "print(evaluate_postfix(postfix_expression))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
-   "id": "0dc4dff8-089b-46a6-a08d-f53ee2fe72c3",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert evaluate_postfix(\"3 4 + 2 *\") == 14\n",
-    "assert evaluate_postfix(\"4 2 3 5 * + *\") == 68 # (4 * (2 + (3 * 5))\n",
-    "assert evaluate_postfix(\"8 4 / 6 2 * +\") == 14 # ((8 / 4) + (6 * 2))"
-   ]
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/solutions/08-binary-trees-exercises.ipynb b/solutions/08-binary-trees-exercises.ipynb
deleted file mode 100644
index 133f662a42749bc099eb5add6c8b2a7a13353145..0000000000000000000000000000000000000000
--- a/solutions/08-binary-trees-exercises.ipynb
+++ /dev/null
@@ -1,657 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "3bae696a-8e88-4a34-89f6-a0f4d9551e9b",
-   "metadata": {},
-   "source": [
-    "# Binary trees\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "7c7461c1-fe15-405b-a2c9-709e6f9c3743",
-   "metadata": {},
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a2428808-27d5-4d42-84b8-01632b1271dd",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "## Exercise 1: Write the code for this binary tree\n",
-    "\n",
-    "_Use a `dict()` data structure for the list of nodes._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "id": "83b91119-09f7-4cba-a87b-19fc4a793e91",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "image/svg+xml": [
-       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
-       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
-       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
-       "<!-- Generated by graphviz version 7.1.0 (20230121.1956)\n",
-       " -->\n",
-       "<!-- Pages: 1 -->\n",
-       "<svg width=\"152pt\" height=\"188pt\"\n",
-       " viewBox=\"0.00 0.00 152.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
-       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
-       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-184 148,-184 148,4 -4,4\"/>\n",
-       "<!-- 0 -->\n",
-       "<g id=\"node1\" class=\"node\">\n",
-       "<title>0</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-162\" rx=\"18\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"99\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
-       "</g>\n",
-       "<!-- 1 -->\n",
-       "<g id=\"node2\" class=\"node\">\n",
-       "<title>1</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"72\" cy=\"-90\" rx=\"18\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"72\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
-       "</g>\n",
-       "<!-- 0&#45;&gt;1 -->\n",
-       "<g id=\"edge1\" class=\"edge\">\n",
-       "<title>0&#45;&gt;1</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M92.74,-144.76C89.64,-136.72 85.81,-126.81 82.3,-117.69\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"85.64,-116.63 78.77,-108.56 79.11,-119.15 85.64,-116.63\"/>\n",
-       "</g>\n",
-       "<!-- 2 -->\n",
-       "<g id=\"node3\" class=\"node\">\n",
-       "<title>2</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"126\" cy=\"-90\" rx=\"18\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"126\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
-       "</g>\n",
-       "<!-- 0&#45;&gt;2 -->\n",
-       "<g id=\"edge4\" class=\"edge\">\n",
-       "<title>0&#45;&gt;2</title>\n",
-       "<path fill=\"none\" stroke=\"red\" d=\"M105.26,-144.76C108.36,-136.72 112.19,-126.81 115.7,-117.69\"/>\n",
-       "<polygon fill=\"red\" stroke=\"red\" points=\"118.89,-119.15 119.23,-108.56 112.36,-116.63 118.89,-119.15\"/>\n",
-       "</g>\n",
-       "<!-- 4 -->\n",
-       "<g id=\"node5\" class=\"node\">\n",
-       "<title>4</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"18\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"18\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
-       "</g>\n",
-       "<!-- 1&#45;&gt;4 -->\n",
-       "<g id=\"edge2\" class=\"edge\">\n",
-       "<title>1&#45;&gt;4</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M61.33,-75.17C54.01,-65.68 44.12,-52.86 35.64,-41.86\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"38.45,-39.78 29.57,-34 32.91,-44.06 38.45,-39.78\"/>\n",
-       "</g>\n",
-       "<!-- 5 -->\n",
-       "<g id=\"node6\" class=\"node\">\n",
-       "<title>5</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"72\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"72\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">5</text>\n",
-       "</g>\n",
-       "<!-- 1&#45;&gt;5 -->\n",
-       "<g id=\"edge3\" class=\"edge\">\n",
-       "<title>1&#45;&gt;5</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M72,-71.7C72,-64.41 72,-55.73 72,-47.54\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"75.5,-47.62 72,-37.62 68.5,-47.62 75.5,-47.62\"/>\n",
-       "</g>\n",
-       "<!-- 3 -->\n",
-       "<g id=\"node4\" class=\"node\">\n",
-       "<title>3</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"126\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"126\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
-       "</g>\n",
-       "<!-- 2&#45;&gt;3 -->\n",
-       "<g id=\"edge5\" class=\"edge\">\n",
-       "<title>2&#45;&gt;3</title>\n",
-       "<path fill=\"none\" stroke=\"red\" d=\"M126,-71.7C126,-64.41 126,-55.73 126,-47.54\"/>\n",
-       "<polygon fill=\"red\" stroke=\"red\" points=\"129.5,-47.62 126,-37.62 122.5,-47.62 129.5,-47.62\"/>\n",
-       "</g>\n",
-       "</g>\n",
-       "</svg>\n"
-      ],
-      "text/plain": [
-       "<graphviz.graphs.Digraph at 0x107df21d0>"
-      ]
-     },
-     "execution_count": 9,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "from graphviz import Digraph\n",
-    "\n",
-    "dot = Digraph()\n",
-    "\n",
-    "dot.node_attr['shape'] = 'circle'\n",
-    "\n",
-    "dot.node('0', label='0')  # Root\n",
-    "dot.node('1')\n",
-    "dot.node('2')\n",
-    "dot.node('3')\n",
-    "dot.node('4')\n",
-    "dot.node('5')\n",
-    "\n",
-    "dot.edge('0', '1')\n",
-    "dot.edge('1', '4')\n",
-    "dot.edge('1', '5')\n",
-    "\n",
-    "dot.edge('0', '2', color='red')\n",
-    "dot.edge('2', '3', color='red')\n",
-    "\n",
-    "\n",
-    "dot # Render the graph"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "1fca57f5-4b3c-4ad8-a4c0-9d1de647abf9",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "_Use a `Dict` data structure for nodes and also for edges edges._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 75,
-   "id": "fa1bce0f-7b06-4d20-8a1b-990bcd03bda9",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-0f290aab7c180fb7",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "T_dict = {\n",
-    "    ### BEGIN CODE\n",
-    "    '0': {\n",
-    "        '1': {\n",
-    "            '4': None,\n",
-    "            '5': None\n",
-    "        },\n",
-    "        '2': {\n",
-    "            '3': None\n",
-    "        },\n",
-    "    }\n",
-    "    ### END CODE\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "cb16382b-e00d-498a-bab2-0b251f93d147",
-   "metadata": {},
-   "source": [
-    "_Use a `Tuple` data structure for nodes and edges._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 92,
-   "id": "a4cbc1d4-5adc-4cda-9c2a-24101bd1bed9",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-ce11e1828bd74e71",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "T_tuple = (\n",
-    "    ### BEGIN CODE\n",
-    "( ), ( )\n",
-    "    ### END CODE\n",
-    ")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "fb0e9336-603c-49c4-9617-9ccecdbf7156",
-   "metadata": {},
-   "source": [
-    "# Exercise: binary search tree\n",
-    "\n",
-    "_We assume we have a binary search tree (BST). Its main property is that for every node, the value of the left children is less than the value of the right children._"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 72,
-   "id": "02513514-0e1b-4c0d-a5fd-ac6b571231b7",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class Node:\n",
-    "    def __init__(self, value):\n",
-    "        self.value = value\n",
-    "        self.left = None\n",
-    "        self.right = None\n",
-    "    def __str__(self):\n",
-    "        return str(self.value)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "055d2cea-4e45-402d-baf8-e50939c94132",
-   "metadata": {},
-   "source": [
-    "Write an `insert` function inserts a value in a tree so it preserves the BST property."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 76,
-   "id": "6492983d-054c-4488-b8ff-57b3878f5b7e",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-b636f3646835e810",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def insert(root, value):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if root is None:\n",
-    "        return Node(value)\n",
-    "    if value < root.value:\n",
-    "        root.left = insert(root.left, value)\n",
-    "    else:\n",
-    "        root.right = insert(root.right, value)\n",
-    "    return root\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 69,
-   "id": "7c2a2f74-a8b8-4cd6-a881-9181efdb7a64",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "<__main__.Node at 0x1069f31c0>"
-      ]
-     },
-     "execution_count": 69,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "a = Node(2)\n",
-    "insert(a, 3)\n",
-    "insert(a, 4)\n",
-    "insert(a, 1)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 74,
-   "id": "10b6d8de-fb38-41e3-92b9-957f04a6f1e4",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/svg+xml": [
-       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
-       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
-       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
-       "<!-- Generated by graphviz version 7.1.0 (20230121.1956)\n",
-       " -->\n",
-       "<!-- Pages: 1 -->\n",
-       "<svg width=\"134pt\" height=\"188pt\"\n",
-       " viewBox=\"0.00 0.00 134.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
-       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
-       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-184 130,-184 130,4 -4,4\"/>\n",
-       "<!-- 2 -->\n",
-       "<g id=\"node1\" class=\"node\">\n",
-       "<title>2</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"63\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"63\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
-       "</g>\n",
-       "<!-- 1 -->\n",
-       "<g id=\"node2\" class=\"node\">\n",
-       "<title>1</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"27\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
-       "</g>\n",
-       "<!-- 2&#45;&gt;1 -->\n",
-       "<g id=\"edge1\" class=\"edge\">\n",
-       "<title>2&#45;&gt;1</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M54.65,-144.76C50.42,-136.55 45.19,-126.37 40.42,-117.09\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"43.68,-115.79 36,-108.49 37.46,-118.99 43.68,-115.79\"/>\n",
-       "</g>\n",
-       "<!-- 3 -->\n",
-       "<g id=\"node3\" class=\"node\">\n",
-       "<title>3</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"99\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
-       "</g>\n",
-       "<!-- 2&#45;&gt;3 -->\n",
-       "<g id=\"edge2\" class=\"edge\">\n",
-       "<title>2&#45;&gt;3</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M71.35,-144.76C75.58,-136.55 80.81,-126.37 85.58,-117.09\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"88.54,-118.99 90,-108.49 82.32,-115.79 88.54,-118.99\"/>\n",
-       "</g>\n",
-       "<!-- 4 -->\n",
-       "<g id=\"node4\" class=\"node\">\n",
-       "<title>4</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"99\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
-       "</g>\n",
-       "<!-- 3&#45;&gt;4 -->\n",
-       "<g id=\"edge3\" class=\"edge\">\n",
-       "<title>3&#45;&gt;4</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M99,-71.7C99,-64.41 99,-55.73 99,-47.54\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"102.5,-47.62 99,-37.62 95.5,-47.62 102.5,-47.62\"/>\n",
-       "</g>\n",
-       "</g>\n",
-       "</svg>\n"
-      ],
-      "text/plain": [
-       "<graphviz.graphs.Digraph at 0x106c3a2f0>"
-      ]
-     },
-     "execution_count": 74,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "visualize_oop(a)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "07ca3602-96fd-43d7-b7ac-54f92124a11d",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "# Exercice: calculate the height using OOP"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 82,
-   "id": "2e65ec3d-8e90-4e25-befb-d779713fa3f2",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class Node:\n",
-    "    def __init__(self, value, l = None, r = None):\n",
-    "        self.value = value\n",
-    "        self.left = l\n",
-    "        self.right = r"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "3bd05d7e-7e0c-4042-9aac-616960849de9",
-   "metadata": {},
-   "source": [
-    "In a recursive way:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 83,
-   "id": "c323b9af-98f6-45d6-9ee2-cffde39a2a16",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-b19dae2393fee8a2",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def recursive_tree_height(node):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if node is None:\n",
-    "        return -1\n",
-    "    left_height = recursive_tree_height(node.left)\n",
-    "    right_height = recursive_tree_height(node.right)\n",
-    "    return max(left_height, right_height) + 1\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 89,
-   "id": "9527fa59-87cf-4216-a7dc-ad0aa3330d4c",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert recursive_tree_height(Node(2)) == 0\n",
-    "assert recursive_tree_height(Node(2, Node(3))) == 1\n",
-    "assert recursive_tree_height(Node(2, Node(3, Node(4)))) == 2"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "7b46712d-472b-4997-90b4-acda29a17fb9",
-   "metadata": {},
-   "source": [
-    "In an interative way:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 84,
-   "id": "6cd2bdcf-d4ad-4103-88ed-ced3fb45f4e8",
-   "metadata": {
-    "nbgrader": {
-     "grade": false,
-     "grade_id": "cell-8cc9bfd56a6fcde6",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def iterative_tree_height(root):\n",
-    "    ### BEGIN SOLUTION\n",
-    "    if root is None:\n",
-    "        return -1\n",
-    "\n",
-    "    level = 0\n",
-    "    current_level = [root]\n",
-    "\n",
-    "    while current_level:\n",
-    "        next_level = []\n",
-    "        for node in current_level:\n",
-    "            if node.left:\n",
-    "                next_level.append(node.left)\n",
-    "            if node.right:\n",
-    "                next_level.append(node.right)\n",
-    "        current_level = next_level\n",
-    "        level += 1\n",
-    "\n",
-    "    return level - 1\n",
-    "    ### END SOLUTION"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 90,
-   "id": "dac217fa-c9db-46ca-91a3-a834c3d0aa38",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert iterative_tree_height(Node(2)) == 0\n",
-    "assert iterative_tree_height(Node(2, Node(3))) == 1\n",
-    "assert iterative_tree_height(Node(2, Node(3, Node(4)))) == 2"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5e50ca4a-6aaf-4620-924a-eb6d8a00efaf",
-   "metadata": {},
-   "source": [
-    "# Utils"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 46,
-   "id": "0c319da6-cee4-447f-b178-0ed04da67273",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from graphviz import Digraph\n",
-    "from IPython.display import display\n",
-    "\n",
-    "class Node:\n",
-    "    def __init__(self, value, l = None, r = None):\n",
-    "        self.value = value\n",
-    "        self.left = l\n",
-    "        self.right = r\n",
-    "\n",
-    "def visualize_oop(root):\n",
-    "    def build(node, dot=None):\n",
-    "        if dot is None:\n",
-    "            dot = graphviz.Digraph(format='png')\n",
-    "\n",
-    "        if node is not None:\n",
-    "            dot.node(str(node.value))\n",
-    "\n",
-    "            if node.left is not None:\n",
-    "                dot.edge(str(node.value), str(node.left.value))\n",
-    "                build(node.left, dot)\n",
-    "\n",
-    "            if node.right is not None:\n",
-    "                dot.edge(str(node.value), str(node.right.value))\n",
-    "                build(node.right, dot)\n",
-    "\n",
-    "        return dot\n",
-    "\n",
-    "    return build(root)\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 47,
-   "id": "b5866309-ceba-4d71-a2e0-5df6e5e18b25",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/svg+xml": [
-       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
-       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
-       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
-       "<!-- Generated by graphviz version 7.1.0 (20230121.1956)\n",
-       " -->\n",
-       "<!-- Pages: 1 -->\n",
-       "<svg width=\"62pt\" height=\"116pt\"\n",
-       " viewBox=\"0.00 0.00 62.00 116.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
-       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 112)\">\n",
-       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-112 58,-112 58,4 -4,4\"/>\n",
-       "<!-- 3 -->\n",
-       "<g id=\"node1\" class=\"node\">\n",
-       "<title>3</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"27\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
-       "</g>\n",
-       "<!-- 2 -->\n",
-       "<g id=\"node2\" class=\"node\">\n",
-       "<title>2</title>\n",
-       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
-       "</g>\n",
-       "<!-- 3&#45;&gt;2 -->\n",
-       "<g id=\"edge1\" class=\"edge\">\n",
-       "<title>3&#45;&gt;2</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M27,-71.7C27,-64.41 27,-55.73 27,-47.54\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"30.5,-47.62 27,-37.62 23.5,-47.62 30.5,-47.62\"/>\n",
-       "</g>\n",
-       "</g>\n",
-       "</svg>\n"
-      ],
-      "text/plain": [
-       "<graphviz.graphs.Digraph at 0x106e17130>"
-      ]
-     },
-     "execution_count": 47,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "visualize_oop(Node(3, Node(2)))"
-   ]
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}