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;"> - <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;"> + <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;"> + <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->1 -->\n", - "<g id=\"edge1\" class=\"edge\">\n", - "<title>0->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->2 -->\n", - "<g id=\"edge4\" class=\"edge\">\n", - "<title>0->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->4 -->\n", - "<g id=\"edge2\" class=\"edge\">\n", - "<title>1->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->5 -->\n", - "<g id=\"edge3\" class=\"edge\">\n", - "<title>1->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->3 -->\n", - "<g id=\"edge5\" class=\"edge\">\n", - "<title>2->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->1 -->\n", - "<g id=\"edge1\" class=\"edge\">\n", - "<title>2->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->3 -->\n", - "<g id=\"edge2\" class=\"edge\">\n", - "<title>2->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->4 -->\n", - "<g id=\"edge3\" class=\"edge\">\n", - "<title>3->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->2 -->\n", - "<g id=\"edge1\" class=\"edge\">\n", - "<title>3->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 -}