diff --git a/README.md b/README.md index 39b7b05ff43b88f138a7ab9c487a80b3d8907a77..c5060ef96de854f8b5ea5f79de12b2680b0d26f2 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,11 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) - [📖 books](https://gitlab.ec-lyon.fr/rvuillem/algo-bsc/-/tree/main/books): books and ressources to prepare the lecture & learn more +⚠️ The class material will be constantly updated, please download it using [Github Desktop](https://github.com/apps/desktop) and update it frequently. ## Course outline and reading list -### [Lecture 1 - **Data structures and complexity**](lectures/01-data-structures-complexity%20slides.pdf) +### Lecture 1 - **Data structures and complexity** - Introduction to data structures - Complexity calculation and analysis (Big O notation) @@ -44,7 +45,7 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) </details> -### [Lab 1 - **Data structures and complexity**](exercices/02-recurion-exercises.ipynb) +### [Lab 1 - **Exercises**](exercices/01-data-structures-complexity-exercises.ipynb) --- @@ -67,7 +68,7 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) - [Think Python](books/thinkpython2.pdf) chapter 5 (Conditionals and recursion) and Real Python [recursion](https://realpython.com/python-recursion/). </details> -### Lab 2 - **Recursion and lists** +### Lab 2 - Exercises --- ### Assignment 1 @@ -88,7 +89,7 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) </details> -### Lab 3 - **Stacks and queues** +### Lab 3 - Exercises --- @@ -103,7 +104,7 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) <summary>📖 </summary> </details> -### Lab 4 - **Priority queues** +### Lab 4 - Exercises --- @@ -122,7 +123,7 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) - [Greedy algorithms](https://en.wikibooks.org/wiki/Algorithms/Greedy_Algorithms) </details> -### Lab 5 - **Programming strategies: divide and conquer, greedy** +### Lab 5 - Exercises --- @@ -139,7 +140,7 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) </details> -### Lab 6 - **Programming strategies: dynamic programming** +### Lab 6 - Exercises --- diff --git a/exercises/01-data-structures-complexity-exercises.ipynb b/exercises/01-data-structures-complexity-exercises.ipynb index eb87658d88cb93d1ccc8a931346c7a6bfeccfcba..c317c455d794219f95885a427ec03a2c5db5b0dd 100644 --- a/exercises/01-data-structures-complexity-exercises.ipynb +++ b/exercises/01-data-structures-complexity-exercises.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "a0b1f35b", + "id": "7f1dc218", "metadata": {}, "source": [ "NAME:" @@ -17,7 +17,8 @@ } }, "source": [ - "# Data Structures and Complexity" + "# UE5 Fundamentals of Algorithms\n", + "# Lab 1: Data structures and complexity" ] }, { @@ -34,40 +35,50 @@ }, { "cell_type": "markdown", - "id": "827ebb43-1e5d-4756-83ba-97af3e36b6af", + "id": "4ed79767-c9a1-44ca-ae78-c75ec0719e11", "metadata": {}, "source": [ - "_For the following question, if a complexity is needed please pick one in this list_" + "# Complexity calculation" + ] + }, + { + "cell_type": "markdown", + "id": "9fae6717-3117-4c16-853e-595b8b27d23d", + "metadata": {}, + "source": [ + "For each of the following questions:\n", + "- Understand the code and what it aims at achieving\n", + "- Fill the cell `# Write an example of use` with an example of use\n", + "- In the `# YOUR CODE HERE` cell, remove `raise NotImplementedError()` and include tests using `assert` and eventually compare to a another implementation (e.g., built-in Python functions)\n", + "- Give the time complexity (from the list `list_complexities` below) as a comment using `#`" ] }, { "cell_type": "code", "execution_count": null, - "id": "b54157fc-f0d5-4689-bf2b-344a608bc5a9", + "id": "2e98d4f6-b8eb-42be-9fc4-b0d1878812d3", "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)\"]" + "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)\", \"Other\"]" ] }, { "cell_type": "markdown", - "id": "568202fd", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, + "id": "90a43e0d-71a7-4f78-9fa6-2adcda12c20c", + "metadata": {}, "source": [ - "### Exercise 1: Identify the complexity of the following function" + "### Example (with solution)\n", + "\n", + "_What does the code below do and what is its complexity?_" ] }, { "cell_type": "code", "execution_count": null, - "id": "431fe8c1-91d1-40f3-a7a4-f4a3770a4a01", + "id": "cd645d2c-3a7e-43b6-9ce1-93f5d16c1a99", "metadata": { "tags": [] }, @@ -75,22 +86,102 @@ "source": [ "def nested_loop_example(L):\n", " n = len(L)\n", + " r = []\n", " for i in range(n):\n", " for j in range(n):\n", - " print(L[i] + L[j])" + " r.append(L[i] + L[j])\n", + " return r" + ] + }, + { + "cell_type": "markdown", + "id": "41fa621f-bb89-4081-9f51-998d1b747a7a", + "metadata": {}, + "source": [ + "_Above is a code that creates an array with the sum of all possible pairs from the array, returned as a new array._" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fc7214b7-f97d-4902-aee9-c19dbb620d71", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use\n", + "L = [1, 2]\n", + "nested_loop_example(L) # [2, 3, 3, 4]" ] }, { "cell_type": "code", "execution_count": null, - "id": "e68b3e9a-418f-4950-9f27-18bb0fe90794", + "id": "9fd9ed1d-7c2d-4470-842a-08f166a5758c", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write tests and complexity\n", + "# YOUR CODE HERE\n", + "assert nested_loop_example([1, 2, 3]) == [2, 3, 4, 3, 4, 5, 4, 5, 6], \"failed to sum positive values\"\n", + "assert nested_loop_example([-1, 0, 1]) == [-2, -1, 0, -1, 0, 1, 0, 1, 2], \"failed to sum positive and negative values\"\n", + "assert nested_loop_example([\"a\", \"b\", \"c\"]) == [\"aa\", \"ab\", \"ac\", \"ba\", \"bb\", \"bc\", \"ca\", \"cb\", \"cc\"], \"failed to concatenate strings\"\n", + "assert nested_loop_example([]) == [], \"failed to handle empty arrays\"\n", + "# Complexity\n", + "# O(n^2)" + ] + }, + { + "cell_type": "markdown", + "id": "1b99cc7f-6aac-4393-b285-7aacbfe24e20", + "metadata": {}, + "source": [ + "### Exercise 1\n", + "_What does the code below do and what is its complexity?_" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9efe9a77-1d0e-4fff-93f0-d6813a9a598d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def sum_of_elements(arr):\n", + " total = 0\n", + " for element in arr:\n", + " total += element\n", + " return total" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9751d52f-6181-4f46-a956-f9d9eef4dc66", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "94882656-f447-4c53-8b7f-330129650d60", "metadata": { "deletable": false, "nbgrader": { "cell_type": "code", - "checksum": "1a3b054c6051bc0e03a25ef29d1c373b", + "checksum": "6e957372065e26aa435819d70aa88af7", "grade": false, - "grade_id": "cell-a06bfe9af33fe998", + "grade_id": "cell-ba46c3faf99e81e9", "locked": false, "schema_version": 3, "solution": true, @@ -100,7 +191,135 @@ }, "outputs": [], "source": [ - "# nested_loop_example_complexity = ?\n", + "# Write tests and complexity\n", + "# Tip compare with the `sum` operator for the tests\n", + "# YOUR CODE HERE\n", + "raise NotImplementedError()\n", + "# Complexity is of .." + ] + }, + { + "cell_type": "markdown", + "id": "a3b9f21c-b48f-4984-a9a8-25a9d7a95300", + "metadata": {}, + "source": [ + "### Exercise 2\n", + "_What does the code below do and what is its complexity?_" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb4ae01b-753c-4860-9332-65566cfad26f", + "metadata": {}, + "outputs": [], + "source": [ + "def find_max(arr):\n", + " max_element = arr[0]\n", + " for element in arr[1:]:\n", + " if element > max_element:\n", + " max_element = element\n", + " return max_element" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95d7bb1e-1cc4-472f-a36e-db36d8792abe", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cf5d179f-8951-429c-aa39-9b55c130f53b", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "0cba9241800ca20d47c46cdea0bd7b20", + "grade": false, + "grade_id": "cell-2aee523bca931ea5", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write tests and complexity\n", + "# Tip compare with the `max` operator for the tests\n", + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "id": "b241c794-4ff6-4661-9c36-c3d52aabf443", + "metadata": {}, + "source": [ + "### Exercise 3\n", + "_What does the code below do and what is its complexity?_" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "163e6954-f4b1-44cd-bd9e-fd740c54f68f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def nested_multiplication(L):\n", + " n = len(L)\n", + " r = []\n", + " for i in range(n):\n", + " r.append(L[i] * L[i])\n", + " return r" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e794cbd9-7669-4f32-835e-a25c930fe880", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "629a734a-a7e7-4684-b10b-c805ae241007", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "40f8815319ad59060b0f8e49463f8ea6", + "grade": false, + "grade_id": "cell-14e2e37a3284fa13", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write tests and complexity\n", + "# Tip compare with the `map` operator for the tests\n", "# YOUR CODE HERE\n", "raise NotImplementedError()" ] @@ -110,7 +329,8 @@ "id": "612dc873-419b-42c5-be36-0accd03ffa79", "metadata": {}, "source": [ - "### Exercise 2: Identify the complexity of the following function" + "### Exercise 4\n", + "_What does the code below do and what is its complexity?_" ] }, { @@ -126,6 +346,18 @@ " return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "e9e39b09-e99f-4e7c-a8b0-1e51cc84e0cf", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use" + ] + }, { "cell_type": "code", "execution_count": null, @@ -134,7 +366,7 @@ "deletable": false, "nbgrader": { "cell_type": "code", - "checksum": "1eadb247ef5c5224aa6800e2d7846174", + "checksum": "f19ccbc05e298f92c29eb26faf02cebe", "grade": false, "grade_id": "cell-34e130eb0c6b7e82", "locked": false, @@ -146,7 +378,7 @@ }, "outputs": [], "source": [ - "# fibonacci_recursive_complexity = ?\n", + "# Write tests and complexity\n", "# YOUR CODE HERE\n", "raise NotImplementedError()" ] @@ -156,7 +388,8 @@ "id": "aa4a6ce7-e542-4b23-8a10-ca0bf93de041", "metadata": {}, "source": [ - "### Exercise 3: Identify the complexity of the following function" + "### Exercise 5\n", + "_What does the code below do and what is its complexity?_" ] }, { @@ -181,6 +414,18 @@ " return -1" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "0350c626-b00f-43c7-942b-4ac1c902addf", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use" + ] + }, { "cell_type": "code", "execution_count": null, @@ -189,7 +434,7 @@ "deletable": false, "nbgrader": { "cell_type": "code", - "checksum": "5f3471162e0167bb6022ece5eed0a4f7", + "checksum": "a71d2ad214282312372603d118c200ae", "grade": false, "grade_id": "cell-ea8595a5923fbb0e", "locked": false, @@ -201,32 +446,345 @@ }, "outputs": [], "source": [ - "# binary_searche_complexity = ?\n", + "# Write tests and complexity\n", + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "id": "44efe8b6-df4b-4a17-a9be-700b445f84d7", + "metadata": { + "tags": [] + }, + "source": [ + "# Write code with a specific complexity" + ] + }, + { + "cell_type": "markdown", + "id": "7d7ea77e-7854-41df-aa0f-af5d6830156a", + "metadata": { + "tags": [] + }, + "source": [ + "For each of the following questions:\n", + "- Carefully read and understand the question (tip: break it down to determine what is being asked).\n", + "- Implement a solution that addresses the question efficiently and correctly\n", + "- Include tests" + ] + }, + { + "cell_type": "markdown", + "id": "a880f0f6-a26e-4c8d-97b0-1e9c2416d706", + "metadata": { + "tags": [] + }, + "source": [ + "### Example (with solution)\n", + "_Write a function `return_value_from_sorted_list` with constant time to return the largest value value from a sorted list (in descending order)_" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "02e79458-77ce-43d9-a9e2-679bae83c8a0", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "99f8afe45256b9c10282055cc7f17ff4", + "grade": false, + "grade_id": "cell-a1c0c8e6e4bcd955", + "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": "0f3802e7-d484-41f3-b4cb-133c34e58ad3", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Example of use\n", + "return_value_from_sorted_list([4, 5, 6]) # 4" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a0cd9fb5-b594-4430-90a7-7264c09d0023", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write tests and complexity\n", + "\n", + "# Tests\n", + "assert return_value_from_sorted_list([3, 2, 1]) == 3\n", + "assert return_value_from_sorted_list([]) == None\n", + "\n", + "# Complexity\n", + "# O(log(1))\"" + ] + }, + { + "cell_type": "markdown", + "id": "5769697b-3729-4c61-adc7-0c91d0a46f2a", + "metadata": { + "tags": [] + }, + "source": [ + "## Exercise 6" + ] + }, { "cell_type": "markdown", - "id": "87b4921b-ef55-4083-b4f1-a3ca5bb7b011", + "id": "e7f85448-2f87-4bf4-ac9e-c49a07dc9cbf", + "metadata": { + "tags": [] + }, + "source": [ + "_Write a function `return_value_from_sorted_list_asc` with constant time to return the largest value value from a sorted list (in descending order)_\n", + "- Tip: check [array operations complexity](https://wiki.python.org/moin/TimeComplexity)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b54de88-8ca2-4f69-b05d-8ef90ea6ad9f", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "4a70580d01376fc9fd294230b7a88e23", + "grade": false, + "grade_id": "cell-90ec8ef2b0282486", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write your code here\n", + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "940568f6-23ec-4188-9913-8ae0f6b10f10", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Example of use\n", + "return_value_from_sorted_list_asc([1, 2, 3]) # 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98602012-9b92-47ee-9865-7b39741d74a4", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "d5168133a1a21dc6c237b7c945764a48", + "grade": false, + "grade_id": "cell-98862ca6e768fef1", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write tests\n", + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "id": "a6e9d4a3-8a8e-4852-860d-ae27fc48deea", "metadata": {}, "source": [ - "### Additional checks (do not change)" + "## Exercise 7\n", + "\n", + "_Write a function that calculates the average of a list in `0(1)` (you may use the `sum` function)_" ] }, { "cell_type": "code", "execution_count": null, - "id": "6e8f2878-ce5f-4cd8-a5a5-7bce8f655ab8", + "id": "65fa7074-a991-432b-af2f-1bd5d20844f1", "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "b915352c779f4792b9fdbcf6b27b8451", + "grade": false, + "grade_id": "cell-57c076594c344cc5", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write your code here\n", + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4cd6ba40-c335-4e50-a4cd-e0a37469a7b9", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Example of use\n", + "L = [1, 2, 3]\n", + "calculate_average(L) # 2.0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4aa7cece-5dba-43ec-bc40-5f8a9f8371da", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "15ff92fbf5885be1d5e10b069ed755eb", + "grade": false, + "grade_id": "cell-0077776e15389c0c", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write tests\n", + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "id": "430d95a7-8690-4dc6-a518-9c92efb59dc6", + "metadata": { + "tags": [] + }, + "source": [ + "## Exercise 8\n", + "\n", + "_Write a function that does the following:_\n", + "- It returns `True` if two integers from a list `L` have a given average `n`. Otherwise, it returns `False`. \n", + "- E.g., for the list `[2, 1, 1, 1]` and `n=1`the function returns `True`.\n", + "- Update this function is it also returns the corresponding values\n", + "- Calculate the complexity" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0cff0f05-4205-43ae-9a3d-eea4a052faee", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "d2ba5b15e29518fcadcbdc72eb76852a", + "grade": false, + "grade_id": "cell-ff6c39af150805f2", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write your code here\n", + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a767d813-b0d8-4181-83a8-69ac322812a3", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Example of use\n", + "two_average([1, 1, 1], 1) # (True, (0, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "444a52cd-c79e-4c58-962d-e1ce715e19d0", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "58c1449f0219d6bd4b6ef7b80002f456", + "grade": false, + "grade_id": "cell-1f269de9c69518f9", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, "tags": [] }, "outputs": [], "source": [ - "assert nested_loop_example_complexity in list_complexities\n", - "assert fibonacci_recursive_complexity in list_complexities\n", - "assert binary_searche_complexity in list_complexities" + "# Write tests and complexity\n", + "# YOUR CODE HERE\n", + "raise NotImplementedError()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d7856b0d-f532-46d1-8ef8-139771b16a99", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/notebooks/01-data-structures-complexity.ipynb b/notebooks/01-data-structures-complexity.ipynb index e1b8d697b1aecdfea66bc0e70aba06d5ce3b158d..22e7783cb0c69c511c3323e35177285b77ef2639 100644 --- a/notebooks/01-data-structures-complexity.ipynb +++ b/notebooks/01-data-structures-complexity.ipynb @@ -13,7 +13,7 @@ }, "source": [ "# UE5 Fundamentals of Algorithms\n", - "## Lecture 1: Introduction\n", + "## Lecture 1: Data structures and complexity\n", "### Ecole Centrale de Lyon, Bachelor of Science in Data Science for Responsible Business\n", "#### Romain Vuillemot\n", "<center><img src=\"figures/Logo_ECL.png\" style=\"width:300px\"></center>" diff --git a/solutions/01-data-structures-complexity-exercises.ipynb b/solutions/01-data-structures-complexity-exercises.ipynb index e72bdcb6cb95ffb836e7dd238a0ba67d6946f37e..9efd413610e3c5c73ec68aad10753225da3d07d6 100644 --- a/solutions/01-data-structures-complexity-exercises.ipynb +++ b/solutions/01-data-structures-complexity-exercises.ipynb @@ -9,7 +9,8 @@ } }, "source": [ - "# Data Structures and Complexity" + "# UE5 Fundamentals of Algorithms\n", + "# Lab 1: Data structures and complexity" ] }, { @@ -26,60 +27,313 @@ }, { "cell_type": "markdown", - "id": "827ebb43-1e5d-4756-83ba-97af3e36b6af", + "id": "4ed79767-c9a1-44ca-ae78-c75ec0719e11", "metadata": {}, "source": [ - "_For the following question, if a complexity is needed please pick one in this list_" + "# Complexity calculation" + ] + }, + { + "cell_type": "markdown", + "id": "9fae6717-3117-4c16-853e-595b8b27d23d", + "metadata": {}, + "source": [ + "For each of the following questions:\n", + "- Understand the code and what it aims at achieving\n", + "- Fill the cell `# Write an example of use` with an example of use\n", + "- In the `# YOUR CODE HERE` cell, remove `raise NotImplementedError()` and include tests using `assert` and eventually compare to a another implementation (e.g., built-in Python functions)\n", + "- Give the time complexity (from the list `list_complexities` below) as a comment using `#`" ] }, { "cell_type": "code", - "execution_count": 1, - "id": "b54157fc-f0d5-4689-bf2b-344a608bc5a9", + "execution_count": 221, + "id": "2e98d4f6-b8eb-42be-9fc4-b0d1878812d3", "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)\"]" + "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)\", \"Other\"]" ] }, { "cell_type": "markdown", - "id": "568202fd", + "id": "90a43e0d-71a7-4f78-9fa6-2adcda12c20c", + "metadata": {}, + "source": [ + "### Example (with solution)\n", + "\n", + "_What does the code below do and what is its complexity?_" + ] + }, + { + "cell_type": "code", + "execution_count": 251, + "id": "cd645d2c-3a7e-43b6-9ce1-93f5d16c1a99", "metadata": { - "slideshow": { - "slide_type": "subslide" + "tags": [] + }, + "outputs": [], + "source": [ + "def nested_loop_example(L):\n", + " n = len(L)\n", + " r = []\n", + " for i in range(n):\n", + " for j in range(n):\n", + " r.append(L[i] + L[j])\n", + " return r" + ] + }, + { + "cell_type": "markdown", + "id": "41fa621f-bb89-4081-9f51-998d1b747a7a", + "metadata": {}, + "source": [ + "_Above is a code that creates an array with the sum of all possible pairs from the array, returned as a new array._" + ] + }, + { + "cell_type": "code", + "execution_count": 252, + "id": "fc7214b7-f97d-4902-aee9-c19dbb620d71", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2, 3, 3, 4]" + ] + }, + "execution_count": 252, + "metadata": {}, + "output_type": "execute_result" } + ], + "source": [ + "# Write an example of use\n", + "L = [1, 2]\n", + "nested_loop_example(L) # [2, 3, 3, 4]" + ] + }, + { + "cell_type": "code", + "execution_count": 225, + "id": "9fd9ed1d-7c2d-4470-842a-08f166a5758c", + "metadata": { + "tags": [] }, + "outputs": [], "source": [ - "### Exercise 1: Identify the complexity of the following function" + "# Write tests and complexity\n", + "# YOUR CODE HERE\n", + "assert nested_loop_example([1, 2, 3]) == [2, 3, 4, 3, 4, 5, 4, 5, 6], \"failed to sum positive values\"\n", + "assert nested_loop_example([-1, 0, 1]) == [-2, -1, 0, -1, 0, 1, 0, 1, 2], \"failed to sum positive and negative values\"\n", + "assert nested_loop_example([\"a\", \"b\", \"c\"]) == [\"aa\", \"ab\", \"ac\", \"ba\", \"bb\", \"bc\", \"ca\", \"cb\", \"cc\"], \"failed to concatenate strings\"\n", + "assert nested_loop_example([]) == [], \"failed to handle empty arrays\"\n", + "# Complexity\n", + "# O(n^2)" + ] + }, + { + "cell_type": "markdown", + "id": "1b99cc7f-6aac-4393-b285-7aacbfe24e20", + "metadata": {}, + "source": [ + "### Exercise 1\n", + "_What does the code below do and what is its complexity?_" ] }, { "cell_type": "code", - "execution_count": 9, - "id": "431fe8c1-91d1-40f3-a7a4-f4a3770a4a01", + "execution_count": 226, + "id": "9efe9a77-1d0e-4fff-93f0-d6813a9a598d", "metadata": { "tags": [] }, "outputs": [], "source": [ - "def nested_loop_example(L):\n", + "def sum_of_elements(arr):\n", + " total = 0\n", + " for element in arr:\n", + " total += element\n", + " return total" + ] + }, + { + "cell_type": "code", + "execution_count": 227, + "id": "9751d52f-6181-4f46-a956-f9d9eef4dc66", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use" + ] + }, + { + "cell_type": "code", + "execution_count": 228, + "id": "94882656-f447-4c53-8b7f-330129650d60", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-ba46c3faf99e81e9", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "15\n" + ] + } + ], + "source": [ + "# Write tests and complexity\n", + "# Tip compare with the `sum` operator for the tests\n", + "### BEGIN SOLUTION\n", + "\n", + "# The code calcules the sum of the values of an array\n", + "arr = [1, 2, 3, 4, 5]\n", + "print(sum_of_elements(arr)) # 15\n", + "\n", + "# Tests\n", + "assert sum_of_elements([1, 2, 3, 4, 5]) == 15\n", + "assert sum_of_elements([]) == 0\n", + "assert sum_of_elements([10]) == 10\n", + "assert sum_of_elements([10, 2]) == sum([10, 2])\n", + "\n", + "# Complexity\n", + "# 0(n)\n", + "### END SOLUTION\n", + "# Complexity is of .." + ] + }, + { + "cell_type": "markdown", + "id": "a3b9f21c-b48f-4984-a9a8-25a9d7a95300", + "metadata": {}, + "source": [ + "### Exercise 2\n", + "_What does the code below do and what is its complexity?_" + ] + }, + { + "cell_type": "code", + "execution_count": 229, + "id": "cb4ae01b-753c-4860-9332-65566cfad26f", + "metadata": {}, + "outputs": [], + "source": [ + "def find_max(arr):\n", + " max_element = arr[0]\n", + " for element in arr[1:]:\n", + " if element > max_element:\n", + " max_element = element\n", + " return max_element" + ] + }, + { + "cell_type": "code", + "execution_count": 230, + "id": "95d7bb1e-1cc4-472f-a36e-db36d8792abe", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use" + ] + }, + { + "cell_type": "code", + "execution_count": 253, + "id": "cf5d179f-8951-429c-aa39-9b55c130f53b", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-2aee523bca931ea5", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write tests and complexity\n", + "# Tip compare with the `max` operator for the tests\n", + "### BEGIN SOLUTION\n", + "\n", + "# The code finds the largest element in an array\n", + "\n", + "# Tests\n", + "assert find_max([3, 1, 4, 1, 5, 9]) == 9\n", + "assert find_max([0, 0, 0]) == 0\n", + "assert find_max([-1, -5, -3]) == -1\n", + "assert find_max([-1, -5, -3]) == max([-1, -5, -3])\n", + "# Complexity\n", + "# 0(n)\n", + "### END SOLUTION" + ] + }, + { + "cell_type": "markdown", + "id": "b241c794-4ff6-4661-9c36-c3d52aabf443", + "metadata": {}, + "source": [ + "### Exercise 3\n", + "_What does the code below do and what is its complexity?_" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "id": "163e6954-f4b1-44cd-bd9e-fd740c54f68f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def nested_multiplication(L):\n", " n = len(L)\n", + " r = []\n", " for i in range(n):\n", - " for j in range(n):\n", - " print(L[i] + L[j])" + " r.append(L[i] * L[i])\n", + " return r" + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "id": "e794cbd9-7669-4f32-835e-a25c930fe880", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use" ] }, { "cell_type": "code", - "execution_count": 10, - "id": "e68b3e9a-418f-4950-9f27-18bb0fe90794", + "execution_count": 254, + "id": "629a734a-a7e7-4684-b10b-c805ae241007", "metadata": { "nbgrader": { "grade": false, - "grade_id": "cell-a06bfe9af33fe998", + "grade_id": "cell-14e2e37a3284fa13", "locked": false, "schema_version": 3, "solution": true, @@ -89,9 +343,19 @@ }, "outputs": [], "source": [ - "# nested_loop_example_complexity = ?\n", + "# Write tests and complexity\n", + "# Tip compare with the `map` operator for the tests\n", "### BEGIN SOLUTION\n", - "nested_loop_example_complexity = \"O(n^2)\"\n", + "\n", + "# The code calculates the square of the values of an array\n", + "L = [3, 4, 5]\n", + "\n", + "# Tests\n", + "assert nested_multiplication(L) == list(map(lambda x: x*x, L))\n", + "assert find_max([0, 0, 0]) == 0\n", + "assert find_max([-1, -5, -3]) == -1\n", + "# Complexity\n", + "# 0(n)\n", "### END SOLUTION" ] }, @@ -100,12 +364,13 @@ "id": "612dc873-419b-42c5-be36-0accd03ffa79", "metadata": {}, "source": [ - "### Exercise 2: Identify the complexity of the following function" + "### Exercise 4\n", + "_What does the code below do and what is its complexity?_" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 155, "id": "76102853-e1f3-4717-8a59-1091195a19eb", "metadata": {}, "outputs": [], @@ -118,7 +383,19 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 156, + "id": "e9e39b09-e99f-4e7c-a8b0-1e51cc84e0cf", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use" + ] + }, + { + "cell_type": "code", + "execution_count": 256, "id": "dead6a52-7996-4eae-9d2a-f75d5d26bbb7", "metadata": { "nbgrader": { @@ -133,9 +410,15 @@ }, "outputs": [], "source": [ - "# fibonacci_recursive_complexity = ?\n", + "# Write tests and complexity\n", "### BEGIN SOLUTION\n", - "fibonacci_recursive_complexity = \"O(n^2)\"\n", + "\n", + "# The code calculates the Fibonnaci number n\n", + "\n", + "# Tests\n", + "assert fibonacci_recursive(2) == 1\n", + "# Complexity\n", + "# O(n)\"\n", "### END SOLUTION" ] }, @@ -144,12 +427,13 @@ "id": "aa4a6ce7-e542-4b23-8a10-ca0bf93de041", "metadata": {}, "source": [ - "### Exercise 3: Identify the complexity of the following function" + "### Exercise 5\n", + "_What does the code below do and what is its complexity?_" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 257, "id": "70af3e43-8053-49c9-ba58-346a3e915bdb", "metadata": { "tags": [] @@ -171,7 +455,19 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 258, + "id": "0350c626-b00f-43c7-942b-4ac1c902addf", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write an example of use" + ] + }, + { + "cell_type": "code", + "execution_count": 259, "id": "9c22866c-b4fc-4228-b0ab-5882d964f5f6", "metadata": { "nbgrader": { @@ -186,33 +482,405 @@ }, "outputs": [], "source": [ - "# binary_searche_complexity = ?\n", + "# Write tests and complexity\n", "### BEGIN SOLUTION\n", - "binary_searche_complexity = \"O(nlog(n))\"\n", + "\n", + "# The code search for a particular value in an array\n", + "L = [1, 3, 5, 7, 9, 11, 13, 15]\n", + "\n", + "# Tests\n", + "assert binary_search(L, 7) == 3, \"find an expected value\"\n", + "assert binary_search(L, 0) == -1, \"find a value not in the array\"\n", + "# Complexity\n", + "# O(log(n))\"\n", "### END SOLUTION" ] }, { "cell_type": "markdown", - "id": "87b4921b-ef55-4083-b4f1-a3ca5bb7b011", + "id": "44efe8b6-df4b-4a17-a9be-700b445f84d7", + "metadata": { + "tags": [] + }, + "source": [ + "# Write code with a specific complexity" + ] + }, + { + "cell_type": "markdown", + "id": "7d7ea77e-7854-41df-aa0f-af5d6830156a", + "metadata": { + "tags": [] + }, + "source": [ + "For each of the following questions:\n", + "- Carefully read and understand the question (tip: break it down to determine what is being asked).\n", + "- Implement a solution that addresses the question efficiently and correctly\n", + "- Include tests" + ] + }, + { + "cell_type": "markdown", + "id": "a880f0f6-a26e-4c8d-97b0-1e9c2416d706", + "metadata": { + "tags": [] + }, + "source": [ + "### Example (with solution)\n", + "_Write a function `return_value_from_sorted_list` with constant time to return the largest value value from a sorted list (in descending order)_" + ] + }, + { + "cell_type": "code", + "execution_count": 263, + "id": "02e79458-77ce-43d9-a9e2-679bae83c8a0", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-a1c0c8e6e4bcd955", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write your code here\n", + "def return_value_from_sorted_list(L):\n", + " if len(L) > 0:\n", + " return L[0]\n", + " else:\n", + " None" + ] + }, + { + "cell_type": "code", + "execution_count": 264, + "id": "0f3802e7-d484-41f3-b4cb-133c34e58ad3", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 264, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Example of use\n", + "return_value_from_sorted_list([4, 5, 6]) # 4" + ] + }, + { + "cell_type": "code", + "execution_count": 265, + "id": "a0cd9fb5-b594-4430-90a7-7264c09d0023", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Write tests and complexity\n", + "\n", + "# Tests\n", + "assert return_value_from_sorted_list([3, 2, 1]) == 3\n", + "assert return_value_from_sorted_list([]) == None\n", + "\n", + "# Complexity\n", + "# O(log(1))\"" + ] + }, + { + "cell_type": "markdown", + "id": "5769697b-3729-4c61-adc7-0c91d0a46f2a", + "metadata": { + "tags": [] + }, + "source": [ + "## Exercise 6" + ] + }, + { + "cell_type": "markdown", + "id": "e7f85448-2f87-4bf4-ac9e-c49a07dc9cbf", + "metadata": { + "tags": [] + }, + "source": [ + "_Write a function `return_value_from_sorted_list_asc` with constant time to return the largest value value from a sorted list (in descending order)_\n", + "- Tip: check [array operations complexity](https://wiki.python.org/moin/TimeComplexity)" + ] + }, + { + "cell_type": "code", + "execution_count": 239, + "id": "3b54de88-8ca2-4f69-b05d-8ef90ea6ad9f", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-90ec8ef2b0282486", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write your code here\n", + "### BEGIN SOLUTION\n", + "def return_value_from_sorted_list_asc(L):\n", + " if len(L) > 0:\n", + " return L.pop()\n", + " else:\n", + " None\n", + "### END SOLUTION" + ] + }, + { + "cell_type": "code", + "execution_count": 240, + "id": "940568f6-23ec-4188-9913-8ae0f6b10f10", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 240, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Example of use\n", + "return_value_from_sorted_list_asc([1, 2, 3]) # 3" + ] + }, + { + "cell_type": "code", + "execution_count": 241, + "id": "98602012-9b92-47ee-9865-7b39741d74a4", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-98862ca6e768fef1", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write tests\n", + "### BEGIN SOLUTION\n", + "\n", + "# Tests\n", + "assert return_value_from_sorted_list_asc([1, 2, 3]) == 3\n", + "### END SOLUTION" + ] + }, + { + "cell_type": "markdown", + "id": "a6e9d4a3-8a8e-4852-860d-ae27fc48deea", "metadata": {}, "source": [ - "### Additional checks (do not change)" + "## Exercise 7\n", + "\n", + "_Write a function that calculates the average of a list in `0(1)` (you may use the `sum` function)_" ] }, { "cell_type": "code", - "execution_count": 8, - "id": "6e8f2878-ce5f-4cd8-a5a5-7bce8f655ab8", + "execution_count": 243, + "id": "65fa7074-a991-432b-af2f-1bd5d20844f1", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-57c076594c344cc5", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write your code here\n", + "### BEGIN SOLUTION\n", + "def calculate_average(L):\n", + " if len(L) == 0:\n", + " return 0\n", + " total_sum = sum(L)\n", + " return total_sum / len(L)\n", + "### END SOLUTION" + ] + }, + { + "cell_type": "code", + "execution_count": 244, + "id": "4cd6ba40-c335-4e50-a4cd-e0a37469a7b9", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2.0" + ] + }, + "execution_count": 244, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Example of use\n", + "L = [1, 2, 3]\n", + "calculate_average(L) # 2.0" + ] + }, + { + "cell_type": "code", + "execution_count": 245, + "id": "4aa7cece-5dba-43ec-bc40-5f8a9f8371da", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-0077776e15389c0c", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write tests\n", + "### BEGIN SOLUTION\n", + "assert calculate_average(L) == 2.0\n", + "### END SOLUTION" + ] + }, + { + "cell_type": "markdown", + "id": "430d95a7-8690-4dc6-a518-9c92efb59dc6", + "metadata": { + "tags": [] + }, + "source": [ + "## Exercise 8\n", + "\n", + "_Write a function that does the following:_\n", + "- It returns `True` if two integers from a list `L` have a given average `n`. Otherwise, it returns `False`. \n", + "- E.g., for the list `[2, 1, 1, 1]` and `n=1`the function returns `True`.\n", + "- Update this function is it also returns the corresponding values\n", + "- Calculate the complexity" + ] + }, + { + "cell_type": "code", + "execution_count": 248, + "id": "0cff0f05-4205-43ae-9a3d-eea4a052faee", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-ff6c39af150805f2", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Write your code here\n", + "### BEGIN SOLUTION\n", + "def two_average(L, n):\n", + " for r, i in enumerate(L):\n", + " for s, j in enumerate(L):\n", + " if not (r == s): \n", + " avg = (i + j) / 2\n", + " if avg == n:\n", + " return True, (r, s)\n", + " return False\n", + "### END SOLUTION" + ] + }, + { + "cell_type": "code", + "execution_count": 249, + "id": "a767d813-b0d8-4181-83a8-69ac322812a3", "metadata": { "tags": [] }, + "outputs": [ + { + "data": { + "text/plain": [ + "(True, (0, 1))" + ] + }, + "execution_count": 249, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Example of use\n", + "two_average([1, 1, 1], 1) # (True, (0, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 250, + "id": "444a52cd-c79e-4c58-962d-e1ce715e19d0", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-1f269de9c69518f9", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, "outputs": [], "source": [ - "assert nested_loop_example_complexity in list_complexities\n", - "assert fibonacci_recursive_complexity in list_complexities\n", - "assert binary_searche_complexity in list_complexities" + "# Write tests and complexity\n", + "### BEGIN SOLUTION\n", + "assert two_average([1, 1, 1], 1) == (True, (0, 1))\n", + "\n", + "### END SOLUTION" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d7856b0d-f532-46d1-8ef8-139771b16a99", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": {