From 962c208acf4086bc6ebdf1579a8e1ae9cd305785 Mon Sep 17 00:00:00 2001 From: Romain Vuillemot <romain.vuillemot@gmail.com> Date: Tue, 3 Oct 2023 08:21:46 +0200 Subject: [PATCH] updates for lecture 4 --- ...data-structures-complexity-exercises.ipynb | 8 +- 01-introduction.ipynb | 12 +- 02-recursion-exercises.ipynb | 1135 ++++++++++++++++ 02-recursion.ipynb | 78 +- 03-lists-search-sort-exercises.ipynb | 84 +- 03-lists-search-sort.ipynb | 501 +++++-- 04-programming-strategies-exercises.ipynb | 546 ++++++++ 04-programming-strategies.ipynb | 781 +++++++++++ ...data-structures-complexity-exercises.ipynb | 240 ++++ solutions/02-recursion-exercises.ipynb | 1203 +++++++++++++++++ 10 files changed, 4436 insertions(+), 152 deletions(-) rename 01-data-structures-complexity-exercices.ipynb => 01-data-structures-complexity-exercises.ipynb (98%) create mode 100644 02-recursion-exercises.ipynb create mode 100644 04-programming-strategies-exercises.ipynb create mode 100644 04-programming-strategies.ipynb create mode 100644 solutions/01-data-structures-complexity-exercises.ipynb create mode 100644 solutions/02-recursion-exercises.ipynb diff --git a/01-data-structures-complexity-exercices.ipynb b/01-data-structures-complexity-exercises.ipynb similarity index 98% rename from 01-data-structures-complexity-exercices.ipynb rename to 01-data-structures-complexity-exercises.ipynb index b46fdf7..de69cd4 100644 --- a/01-data-structures-complexity-exercices.ipynb +++ b/01-data-structures-complexity-exercises.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "608c95b1", + "id": "136ec072", "metadata": {}, "source": [ "# UE5 Fundamentals of Algorithms\n", @@ -23,7 +23,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a934feef", + "id": "b8c8e619", "metadata": {}, "outputs": [], "source": [ @@ -33,7 +33,7 @@ }, { "cell_type": "markdown", - "id": "b498a6a2", + "id": "986b50e4", "metadata": {}, "source": [ "---" @@ -74,7 +74,7 @@ { "cell_type": "code", "execution_count": null, - "id": "761a1dba-a197-4206-92a2-78920211f9f1", + "id": "b54157fc-f0d5-4689-bf2b-344a608bc5a9", "metadata": { "tags": [] }, diff --git a/01-introduction.ipynb b/01-introduction.ipynb index b6070ed..5f11e83 100644 --- a/01-introduction.ipynb +++ b/01-introduction.ipynb @@ -331,7 +331,7 @@ "source": [ "### Exercice: Leap year\n", "\n", - "Write a function `is_leap_year` that takes a year as input and returns `True` if it's a leap year and `False``\n", + "Write a function `is_leap_year` that takes a year as input and returns `True` if it's a leap year and `False`\n", " otherwise. The function follows the rules for leap year determination:\n", "\n", "- A year that is divisible by 4 is a leap year.\n", @@ -1530,7 +1530,7 @@ } }, "source": [ - "### Exercice: remove duplicatas from a list (using dicts)\n", + "### Exercice: detect duplicates from a list (using dicts)\n", "\n", "Write an algorithm validates the following:\n", "\n", @@ -2176,14 +2176,6 @@ "plt.grid()\n", "plt.show()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a3c54d0d", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/02-recursion-exercises.ipynb b/02-recursion-exercises.ipynb new file mode 100644 index 0000000..09f693b --- /dev/null +++ b/02-recursion-exercises.ipynb @@ -0,0 +1,1135 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "996ed570", + "metadata": {}, + "source": [ + "# UE5 Fundamentals of Algorithms\n", + "## Exercices\n", + "### Ecole Centrale de Lyon, Bachelor of Science in Data Science for Responsible Business\n", + "#### [Romain Vuillemot](https://romain.vuillemot.net/)\n", + "\n", + "Before you turn this problem in:\n", + "- make sure everything runs as expected. \n", + " - first, **restart the kernel** (in the menubar, select Kernel$\\rightarrow$Restart) \n", + " - then **run all cells** (in the menubar, select Cell$\\rightarrow$Run All).\n", + "- make sure you fill in any place that says `YOUR CODE HERE` or \"YOUR ANSWER HERE\"\n", + "- remove `raise NotImplementedError()` to get started with your answer\n", + "- bonus points (at the end of this notebook) are optionals\n", + "- write your name (and collaborators as a list if any) below:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a0151651", + "metadata": {}, + "outputs": [], + "source": [ + "ID = \"\"\n", + "COLLABORATORS_ID = []" + ] + }, + { + "cell_type": "markdown", + "id": "86da338c", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "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" + ] + }, + { + "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": "code", + "execution_count": null, + "id": "159b6d78-03ae-4cf8-8545-e822b7160b32", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def iterative_reverse_string(s):\n", + " reversed_str = \"\"\n", + " for char in s:\n", + " reversed_str = char + reversed_str\n", + " return reversed_str" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43e10b0c", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "5ab8f3c9-ddee-45ab-a013-fdd67d9853e0", + "metadata": {}, + "source": [ + "### Example 5: convert an interative suite into a recursive tail function" + ] + }, + { + "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 an annagram\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": "1edb53556b907062a6d2f29282317e03", + "grade": false, + "grade_id": "annagram_rec", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def annagram_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": [ + "annagram_rec(\"laval\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cf6fa61a-7c6f-4a32-96c2-b9fd50deacc6", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "22a5df98d007ceb58975b5877958e3f8", + "grade": true, + "grade_id": "correct_annagram_rec", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "assert annagram_rec(\"\")\n", + "assert annagram_rec(\"AA\")\n", + "assert not annagram_rec(\"ABC\")\n", + "assert annagram_rec(\"ABA\")\n", + "assert annagram_rec(\"LAVAL\")" + ] + }, + { + "cell_type": "markdown", + "id": "798c2875-7940-488a-8458-ad08f6a71c70", + "metadata": {}, + "source": [ + "### Example 7: Calculate GCD\n" + ] + }, + { + "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 is sorted" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1661dfb5-88f2-411f-8fe2-63bbaa29ce72", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "9fcedc9d6262baf07013d0b6f4e8175d", + "grade": false, + "grade_id": "calculate_average_recursive", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def is_sorted(lst):\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": "9cdabb05d7be086c1b769672a158fdc6", + "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])" + ] + }, + { + "cell_type": "markdown", + "id": "79eef392-1d3d-46c0-aeee-ac805686e6f1", + "metadata": {}, + "source": [ + "### Example 9: Check for prime number" + ] + }, + { + "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": "01c4970fffe483944b93049b5d8404a0", + "grade": false, + "grade_id": "count_occurrences", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def count_occurrences(arr, 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 points" + ] + }, + { + "cell_type": "markdown", + "id": "7fdcd705-dc0b-4614-8e27-9ba62f8fe442", + "metadata": {}, + "source": [ + "### Exercise 1: 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 1: 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": "b8bc657e-d491-4851-aa8c-ac2f2eac0841", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "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)]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d601b2f3-c33b-4ed2-81be-639ce1ffab76", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f252530-7817-444c-ae10-d7b3bca87f2d", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0976f7c2-4375-4d76-a6c1-9e729a6c8aeb", + "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/02-recursion.ipynb b/02-recursion.ipynb index 96f87fa..4ce9a3d 100644 --- a/02-recursion.ipynb +++ b/02-recursion.ipynb @@ -66,6 +66,64 @@ "* Similarity to proof by induction." ] }, + { + "cell_type": "markdown", + "id": "1168f89b", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Example 0: countdown" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "687dc73a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n", + "4\n", + "3\n", + "2\n", + "1\n", + "Blastoff!\n" + ] + } + ], + "source": [ + "def countdown(n):\n", + " if n <= 0: # base case\n", + " print(\"Blastoff!\")\n", + " else:\n", + " print(n)\n", + " countdown(n - 1) # recursive call\n", + "\n", + "countdown(5)" + ] + }, + { + "cell_type": "markdown", + "id": "8d305f45", + "metadata": {}, + "source": [ + "Here's how the countdown(5) call would work:\n", + "<pre>\n", + "countdown(5) prints 5 and calls countdown(4)\n", + "countdown(4) prints 4 and calls countdown(3)\n", + "countdown(3) prints 3 and calls countdown(2)\n", + "countdown(2) prints 2 and calls countdown(1)\n", + "countdown(1) prints 1 and calls countdown(0)\n", + "countdown(0) prints \"Blastoff!\" and returns without making another recursive call.\n", + "</pre>" + ] + }, { "cell_type": "markdown", "id": "0f552254", @@ -454,7 +512,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 42, "id": "021f2066", "metadata": {}, "outputs": [], @@ -462,12 +520,12 @@ "def print_desc(n):\n", " if n > 0:\n", " print(\" \" * n, \" n= \" , n ,\" brefore recursive call\")\n", - " ecrire_desc (n - 1)" + " print_desc (n - 1)" ] }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 43, "id": "ed36ce86", "metadata": {}, "outputs": [ @@ -476,8 +534,8 @@ "output_type": "stream", "text": [ " n= 3 brefore recursive call\n", - " n= 2 avant l'appel récursif\n", - " n= 1 avant l'appel récursif\n" + " n= 2 brefore recursive call\n", + " n= 1 brefore recursive call\n" ] } ], @@ -487,7 +545,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 44, "id": "5223a19b", "metadata": { "slideshow": { @@ -498,13 +556,13 @@ "source": [ "def print_asc(n) :\n", " if n > 0:\n", - " ecrire_asc(n - 1) \n", + " print_asc(n - 1) \n", " print(\" \" * n, \" n= \" , n ,\" after recrusive call\")" ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 45, "id": "a4262dee", "metadata": {}, "outputs": [ @@ -512,8 +570,8 @@ "name": "stdout", "output_type": "stream", "text": [ - " n= 1 après l'appel récursif\n", - " n= 2 après l'appel récursif\n", + " n= 1 after recrusive call\n", + " n= 2 after recrusive call\n", " n= 3 after recrusive call\n" ] } diff --git a/03-lists-search-sort-exercises.ipynb b/03-lists-search-sort-exercises.ipynb index 3d5c261..ad1a423 100644 --- a/03-lists-search-sort-exercises.ipynb +++ b/03-lists-search-sort-exercises.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "d8056b8c", + "id": "5cbf5ca9", "metadata": {}, "source": [ "# UE5 Fundamentals of Algorithms\n", @@ -23,7 +23,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9c5894f5", + "id": "43da1f45", "metadata": {}, "outputs": [], "source": [ @@ -33,7 +33,7 @@ }, { "cell_type": "markdown", - "id": "838b13ee", + "id": "4d0c6ee6", "metadata": {}, "source": [ "---" @@ -55,14 +55,26 @@ "---" ] }, + { + "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": "9d813205-b709-42ab-b414-6f3fc947022a", "metadata": {}, "source": [ - "## Exerccise 1: Search in a list with an odd index\n", + "## 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`. If the target element is not in the list, return -1. The target index should also be of an odd value (eg 0, 2, 4, ..)." + "_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`._" ] }, { @@ -95,19 +107,6 @@ "execution_count": null, "id": "f280eeea-4812-4a30-80b5-3fe1cafa9283", "metadata": { - "deletable": false, - "editable": false, - "nbgrader": { - "cell_type": "code", - "checksum": "e508e1baca64296eb559208993ee6289", - "grade": true, - "grade_id": "correct_search_list", - "locked": true, - "points": 1, - "schema_version": 3, - "solution": false, - "task": false - }, "tags": [] }, "outputs": [], @@ -120,6 +119,19 @@ "execution_count": null, "id": "423d2637-8bd6-4e8f-95ff-2765dae5bce7", "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "68b51ac31cc882ccdf9200c444d4e30d", + "grade": true, + "grade_id": "correct_correct_search_list", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, "tags": [] }, "outputs": [], @@ -137,9 +149,9 @@ "id": "6d8dc6cd-aad0-42a9-b768-6a1a5289e354", "metadata": {}, "source": [ - "## Exerccise 2: Sort a list of tuples\n", + "## 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" + "_Given a list of lists of length N, sort by the N-th element of the list._" ] }, { @@ -150,7 +162,7 @@ "deletable": false, "nbgrader": { "cell_type": "code", - "checksum": "d36956e43a1d9a594625212c58f4560a", + "checksum": "18319fc9882c760de9d2f2dde25e2c76", "grade": false, "grade_id": "sort_list_of_lists_by_nth_element", "locked": false, @@ -164,8 +176,7 @@ "source": [ "def sort_list_of_lists_by_nth_element(list_of_lists, N):\n", " # YOUR CODE HERE\n", - " raise NotImplementedError()\n", - "# Example usage:\n" + " raise NotImplementedError()" ] }, { @@ -222,7 +233,9 @@ "id": "0bbda1ba-a5e7-4a1d-a742-84d0215b1e24", "metadata": {}, "source": [ - "## Exerccise 3: Access a list element" + "## Exercise 3: Access a list element\n", + "\n", + "_Given an input list `L`, and `index` value, access a given `key` and return the value._" ] }, { @@ -273,7 +286,7 @@ "editable": false, "nbgrader": { "cell_type": "code", - "checksum": "c77eefc574735feb146d00c86553b601", + "checksum": "efa0cb4d52536298b425a5e9d5154374", "grade": true, "grade_id": "correct_access_dict_element", "locked": true, @@ -288,14 +301,8 @@ "source": [ "example_list = [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]\n", "assert access_dict_element(example_list, 0, 'name') == 'Alice'\n", - "\n", - "# Example 2: Accessing a non-existing key in a dictionary at a valid index\n", "assert access_dict_element(example_list, 1, 'city') is None\n", - "\n", - "# Example 3: Accessing an index that is out of range\n", "assert access_dict_element(example_list, 2, 'name') is None\n", - "\n", - "# Example 4: Accessing a valid index but with a key that doesn't exist\n", "assert access_dict_element(example_list, 0, 'city') is None" ] }, @@ -306,9 +313,9 @@ "tags": [] }, "source": [ - "## Exerccise 4: Remove Elements from a List\n", + "## 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. The `condition` is a function that accepts an element from the list as its argument and returns a boolean value. The function `remove_elements` should remove all elements from the list for which the `condition` function returns `True`." + "_Write a Python function `remove_elements(L, condition)` that takes a list `L` and a function `condition` as input._" ] }, { @@ -372,7 +379,7 @@ "editable": false, "nbgrader": { "cell_type": "code", - "checksum": "7d18e8b7e4619abfc3e78fb2f2801892", + "checksum": "d60a1be7322087e5612fb15fc5677539", "grade": true, "grade_id": "correct_remove_elements", "locked": true, @@ -385,17 +392,14 @@ }, "outputs": [], "source": [ - "# Test 1: Remove elements greater than 10\n", "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]\n", + "assert test_list_1 == [5, 9, 3], \"Remove greater than 30\"\n", "\n", - "# Test 2: Remove negative elements\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]\n", + "assert test_list_2 == [7, 2, 0, 8], \"Remove negative elements\"\n", "\n", - "# Test 3: Remove elements based on a custom condition\n", "def custom_condition(x):\n", " return x % 3 == 0\n", "test_list_3 = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n", @@ -408,7 +412,7 @@ "\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 elements to remove\"" + "assert test_list_5 == [10, 20, 30, 40], \"No element to remove\"" ] }, { diff --git a/03-lists-search-sort.ipynb b/03-lists-search-sort.ipynb index 3809862..b1084b9 100644 --- a/03-lists-search-sort.ipynb +++ b/03-lists-search-sort.ipynb @@ -24,25 +24,6 @@ "<center><img src=\"figures/Logo_ECL.png\" style=\"width:300px\"></center>\n" ] }, - { - "cell_type": "markdown", - "id": "6341504d", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "---\n", - "TODO\n", - "- \n", - "- tp-pythonneries.pdf\n", - "Static and dynamic arrays\n", - "Singly linked lists\n", - "Doubly linked lists\n", - "Circular linked lists" - ] - }, { "cell_type": "markdown", "id": "fbbc2f0d", @@ -130,14 +111,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "33da6137", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "3\n" + ] + } + ], "source": [ "L = [1, 2, 3]\n", "\n", - "for val in tab:\n", + "for val in L:\n", " print(val)" ] }, @@ -155,10 +146,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "05a3d562", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "False\n" + ] + } + ], "source": [ "def estordonnee(liste):\n", "\n", @@ -187,7 +187,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "5aad3402", "metadata": {}, "outputs": [], @@ -205,24 +205,43 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "37c3b4a7", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "1.5497207641601563e-07" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "compute_average(20)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "9c4be228", "metadata": { "slideshow": { "slide_type": "-" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 99, 100, 3, 4, 5]\n" + ] + } + ], "source": [ "my_list = [1, 2, 3, 4, 5]\n", "insert_elements = [99, 100]\n", @@ -246,7 +265,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "8a5dd42f", "metadata": { "nbgrader": { @@ -269,7 +288,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "a3e4ed1f", "metadata": { "nbgrader": { @@ -282,7 +301,15 @@ "task": false } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3 found at index 2.\n" + ] + } + ], "source": [ "L = [1, 2, 3, 4, 5]\n", "element_to_find = 3\n", @@ -323,22 +350,20 @@ ] }, { - "cell_type": "code", - "execution_count": 22, - "id": "0d5eeb2c", + "cell_type": "markdown", + "id": "57327e04", "metadata": { "slideshow": { "slide_type": "subslide" } }, - "outputs": [], "source": [ "### Example: Binary search (pseudo code)" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 10, "id": "1197437b", "metadata": { "slideshow": { @@ -359,18 +384,17 @@ " left, right = 0, len(arr) - 1\n", "\n", " while left <= right:\n", - " mid = (left + right) // 2 # Calculate the middle index\n", + " mid = (left + right) // 2 \n", "\n", " if arr[mid] == target:\n", - " return mid # Element found, return its index\n", + " return mid \n", " elif arr[mid] < target:\n", - " left = mid + 1 # Search the right half\n", + " left = mid + 1 \n", " else:\n", - " right = mid - 1 # Search the left half\n", + " right = mid - 1 \n", "\n", - " return -1 # Element not found\n", + " return -1 \n", "\n", - "# Example usage:\n", "ordered_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", "target_element = 5\n", "result = binary_search(ordered_list, target_element)\n", @@ -412,7 +436,7 @@ } }, "source": [ - "### All the ways to sort a list " + "### Many ways to sort a list " ] }, { @@ -429,48 +453,169 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "id": "01e4d112", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]\n" + ] + } + ], "source": [ "numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]\n", - "sorted_numbers = sorted(numbers)" + "sorted(numbers) # in place operation (changes the original variable)\n", + "print(sorted_numbers)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "id": "e2c9277a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[9, 6, 5, 5, 5, 4, 3, 3, 2, 1, 1]\n" + ] + } + ], "source": [ "numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]\n", - "numbers.sort(reverse=True)" + "numbers.sort(reverse=True) # did not change the original variable\n", + "print(numbers)" ] }, { "cell_type": "code", - "execution_count": null, - "id": "26d6dad8", + "execution_count": 92, + "id": "34975051", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['date', 'apple', 'cherry', 'banana']\n" + ] + } + ], + "source": [ + "words = ['apple', 'cherry', 'banana', 'date']\n", + "sorted_words = sorted(words, key=len)\n", + "print(sorted_words)" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "id": "7fcf7380", "metadata": {}, "outputs": [], "source": [ - "numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]\n", - "numbers.sort()" + "import functools" ] }, { "cell_type": "code", - "execution_count": null, - "id": "34975051", + "execution_count": 98, + "id": "547f8c13", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['apple', 'banana', 'cherry', 'date']" + ] + }, + "execution_count": 98, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "words = ['apple', 'cherry', 'banana', 'date']\n", + "sorted(words, key=functools.cmp_to_key(order_by_alphabetical_order))" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "id": "357d7c7a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['apple', 'banana', 'cherry', 'date']" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "words = ['apple', 'cherry', 'banana', 'date']\n", + "sorted(words, key=functools.cmp_to_key(lambda x, y: ord(x[0]) - ord(y[0])))" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "id": "90102b6a", "metadata": {}, "outputs": [], "source": [ - "words = ['apple', 'banana', 'cherry', 'date']\n", - "sorted_words = sorted(words, key=len)" + "def order_by_alphabetical_order(a, b):\n", + " return ord(a[0]) - ord(b[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "id": "6afa72f9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "order_by_alphabetical_order(\"cherry\", \"banana\")" ] }, + { + "cell_type": "code", + "execution_count": 53, + "id": "a0c076fa", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "66" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, { "cell_type": "markdown", "id": "ee60b8ff", @@ -619,6 +764,49 @@ " print(item)" ] }, + { + "cell_type": "code", + "execution_count": 11, + "id": "ff445529", + "metadata": {}, + "outputs": [], + "source": [ + "def fib_generator():\n", + " a, b = 0, 1\n", + " while True:\n", + " yield a\n", + " a, b = b, a + b" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "e8aa68b2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "1\n", + "2\n", + "3\n", + "5\n", + "8\n", + "13\n", + "21\n", + "34\n" + ] + } + ], + "source": [ + "fib = fib_generator()\n", + "for _ in range(10):\n", + " print(next(fib))" + ] + }, { "cell_type": "markdown", "id": "0a882d1d", @@ -642,16 +830,6 @@ "- On the other hand, it requires linear search time (unlike arrays), and can be problematic for implementing a stack.\n" ] }, - { - "cell_type": "code", - "execution_count": 19, - "id": "f248b881", - "metadata": {}, - "outputs": [], - "source": [ - "## Linked list (cont.)" - ] - }, { "cell_type": "code", "execution_count": 18, @@ -702,26 +880,23 @@ "traverse()\n" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "5c865215", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "id": "28564ab2", - "metadata": {}, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, "source": [ "## Filter\n", - "\n" + "\n", + "Return a sublist given a criteri" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "id": "3012f2e3", "metadata": {}, "outputs": [ @@ -731,7 +906,7 @@ "[6, 7, 8, 9]" ] }, - "execution_count": 9, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -744,20 +919,56 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "5c0860da", + "execution_count": 14, + "id": "8de20627", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[2, 3]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "## Map" + "[1, 2, 3][1:]" + ] + }, + { + "cell_type": "markdown", + "id": "fe92613c", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Map\n", + "\n", + "Apply a function a list of values" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "435094a4", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "list(map(lambda x : x * x, x))" ] @@ -765,15 +976,129 @@ { "cell_type": "code", "execution_count": null, - "id": "5575cf08", + "id": "fb30b1ce", "metadata": {}, "outputs": [], "source": [] }, + { + "cell_type": "code", + "execution_count": 15, + "id": "f5b8712a", + "metadata": {}, + "outputs": [], + "source": [ + "L = [1, 2, 3]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "edfc966b", + "metadata": {}, + "outputs": [], + "source": [ + "L.append(4)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "f61d0ac8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 2, 3, 4]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "L" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "fe60f8fc", + "metadata": {}, + "outputs": [], + "source": [ + "L = L + [5, 6, 7]" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "e30fa183", + "metadata": {}, + "outputs": [], + "source": [ + "L.extend([2, 4, 5])" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "e96a50b2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 2, 3, 4, [5, 6, 7], 2, 4, 5, 5, 6, 7, 2, 4, 5]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "L" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "bd7930ff", + "metadata": {}, + "outputs": [], + "source": [ + "L = [3, 4, 5]" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "601e1691", + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "10 is not in list", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[34], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mL\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mindex\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m)\u001b[49m\n", + "\u001b[0;31mValueError\u001b[0m: 10 is not in list" + ] + } + ], + "source": [ + "L.index(10)" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "fb30b1ce", + "id": "8185d9b9", "metadata": {}, "outputs": [], "source": [] diff --git a/04-programming-strategies-exercises.ipynb b/04-programming-strategies-exercises.ipynb new file mode 100644 index 0000000..386d6b5 --- /dev/null +++ b/04-programming-strategies-exercises.ipynb @@ -0,0 +1,546 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1523c46c", + "metadata": {}, + "source": [ + "# UE5 Fundamentals of Algorithms\n", + "## Exercices\n", + "### Ecole Centrale de Lyon, Bachelor of Science in Data Science for Responsible Business\n", + "#### [Romain Vuillemot](https://romain.vuillemot.net/)\n", + "\n", + "Before you turn this problem in:\n", + "- make sure everything runs as expected. \n", + " - first, **restart the kernel** (in the menubar, select Kernel$\\rightarrow$Restart) \n", + " - then **run all cells** (in the menubar, select Cell$\\rightarrow$Run All).\n", + "- make sure you fill in any place that says `YOUR CODE HERE` or \"YOUR ANSWER HERE\"\n", + "- remove `raise NotImplementedError()` to get started with your answer\n", + "- bonus points (at the end of this notebook) are optionals\n", + "- write your name (and collaborators as a list if any) below:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c984c437", + "metadata": {}, + "outputs": [], + "source": [ + "ID = \"\"\n", + "COLLABORATORS_ID = []" + ] + }, + { + "cell_type": "markdown", + "id": "81f8cbf6", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "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`._" + ] + }, + { + "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": [ + "print(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": "dce1654749f72d16fa3d21a731f0a7ff", + "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], 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" + ] + }, + { + "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\n", + "- define a `closest_point_naive`function using `math.inf`as initial value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0be305c3-c054-4092-b041-bd7e705e2178", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "ad1d7f9ad703f728fac843c9b6d4cbe1", + "grade": false, + "grade_id": "cell-8738237c4c6682e4", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import math\n", + "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": "a5504d9e67deeb2651dfc058b5314bb8", + "grade": false, + "grade_id": "cell-9ca280911ed42034", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def closest_point_naive(P, n):\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, len(points))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5d875175-45c3-4594-a434-23e15cfb88f7", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "17cb3a74f60bcbe305bce69a5b45da65", + "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", + "n1 = len(points1)\n", + "\n", + "result1 = closest_point_naive(points1, n1)\n", + "expected_result1 = 0.0 \n", + "print(result1)\n", + "assert math.isclose(result1, expected_result1, rel_tol=1e-9), f\"Test Case 1 failed: {result1} != {expected_result1}\"" + ] + }, + { + "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", + "closest1 = closest_point_naive_pair(points1)\n", + "assert closest1 == ((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": "725597ac005b370c6135a3f1920beb2c", + "grade": false, + "grade_id": "merge_sort", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def merge_sort(arr): \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": "3ca9c06b9c5d3b2b5728138d821e650c", + "grade": true, + "grade_id": "correct_merge_sort", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "L = [4, 2, 3]\n", + "assert merge_sort(L) == sorted(L)" + ] + } + ], + "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/04-programming-strategies.ipynb b/04-programming-strategies.ipynb new file mode 100644 index 0000000..4d336d8 --- /dev/null +++ b/04-programming-strategies.ipynb @@ -0,0 +1,781 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "90ae134f", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# UE5 Fundamentals of Algorithms\n", + "## Lecture 4: Programming strategies\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>" + ] + }, + { + "cell_type": "markdown", + "id": "b3ce5394", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Programming strategies\n", + "\n", + "> A programming strategy are algorithms aimed at solving a specific problem in a precise manner.\n", + "\n", + "Examples of Strategies:\n", + "\n", + "- **Divide and Conquer:** Divide a problem into simpler sub-problems, solve the sub-problems, and then combine the solutions to solve the original problem.\n", + "\n", + "- **Dynamic Programming:** Solve a problem by breaking it down into sub-problems, calculating and memorizing the results of sub-problems to avoid unnecessary recomputation.\n", + "\n", + "- **Greedy Algorithm:** Make a series of choices that seem locally optimal at each step to find a solution, with the hope that the result will be globally optimal as well.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "19c91bb3", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Divide and conquer\n", + "\n", + "> The **Divide and Conquer** strategy involves breaking a complex problem into smaller, similar subproblems, solving them recursively, and then combining their solutions to address the original problem efficiently.\n", + "\n", + "1. **Divide:** Divide the original problem into subproblems of the same type.\n", + "\n", + "2. **Conquer:** Solve each of these subproblems recursively.\n", + "\n", + "3. **Combine:** Combine the answers appropriately.\n", + "\n", + "_It is very close to the recursive approach_\n" + ] + }, + { + "cell_type": "markdown", + "id": "c84c6bdd", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "\n", + "### Examples of divide and conquer algorithms:\n", + "\n", + "- Binary search\n", + "- Quick sort and merge sort\n", + "- Map Reduce\n", + "- Others: Fast multiplication (Karatsuba)" + ] + }, + { + "cell_type": "markdown", + "id": "fa188fcb", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Binary search\n", + "\n", + "_Given a sorted list, find or insert a specific value while keeping the order._\n", + "\n", + "<img src=\"figures/recherche-dichotomique.png\" style=\"width:500px\">" + ] + }, + { + "cell_type": "markdown", + "id": "ba8f8ab0", + "metadata": {}, + "source": [ + "## Quick sort\n", + "\n", + "<img src=\"figures/quicksort.png\" style=\"height:400px\">" + ] + }, + { + "cell_type": "markdown", + "id": "2ba80ce1", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Merge sort\n", + "\n", + "<img src=\"figures/tri-fusion.png\" style=\"width:500px\">" + ] + }, + { + "cell_type": "markdown", + "id": "68bf754c", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Map reduce\n", + "\n", + "<img src=\"figures/Mapreduce.png\" style=\"width:700px\">" + ] + }, + { + "cell_type": "markdown", + "id": "5e864f8b", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Map reduce (without map reduce..)" + ] + }, + { + "cell_type": "markdown", + "id": "32ad76f1", + "metadata": {}, + "source": [ + "_Calculate the sum of squares values from a list of numerical values._" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "0df729b8", + "metadata": {}, + "outputs": [], + "source": [ + "data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "27efe14e", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[(1, 1), (4, 2), (9, 3), (16, 4), (25, 5), (36, 6), (49, 7), (64, 8), (81, 9), (100, 10)]\n" + ] + } + ], + "source": [ + "result = {}\n", + "for num in data:\n", + " square = num * num\n", + " if square in result:\n", + " result[square] += num\n", + " else:\n", + " result[square] = num\n", + "\n", + "final_result = list(result.items())\n", + "\n", + "print(final_result)" + ] + }, + { + "cell_type": "markdown", + "id": "68e3c445", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Map reduce (Python)\n", + "\n", + "_Using a \"combine\" step._" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "e4773ca8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[(1, [1]), (2, [4]), (3, [9]), (4, [16]), (5, [25]), (6, [36]), (7, [49]), (8, [64]), (9, [81]), (10, [100])]\n" + ] + } + ], + "source": [ + "data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", + "\n", + "def mapper(numbers):\n", + " result = []\n", + " for num in numbers: # calculate the squares\n", + " result.append((num, num * num))\n", + " return result\n", + "\n", + "def reducer(pairs):\n", + " result = {}\n", + " for key, value in pairs: # sums the squares\n", + " if key in result:\n", + " result[key] += value \n", + " else:\n", + " result[key] = value\n", + " return result.items()\n", + "\n", + "chunk_size = 2\n", + "chunks = [data[i:i+chunk_size] for i in range(0, len(data), chunk_size)]\n", + "\n", + "mapped_data = [mapper(chunk) for chunk in chunks] # map\n", + "\n", + "grouped_data = {}# combine\n", + "for chunk in mapped_data:\n", + " for key, value in chunk:\n", + " if key in grouped_data:\n", + " grouped_data[key].append(value)\n", + " else:\n", + " grouped_data[key] = [value]\n", + "\n", + "reduced_data = [reducer(list(grouped_data.items()))] # reduce\n", + "\n", + "# Flatten the result\n", + "final_result = []\n", + "for item in reduced_data:\n", + " final_result.extend(item)\n", + "\n", + "print(final_result)" + ] + }, + { + "cell_type": "markdown", + "id": "d6f04202", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Discussion \n", + "\n", + "- Similarities with recursion by dividing a problem in a sub-problem\n", + "\n", + "- But with a combination step\n", + "\n", + "- Can be implemented in a non-recursive way\n", + "\n", + "- Often a $n log(n)$ complexity" + ] + }, + { + "cell_type": "markdown", + "id": "67fdbeea", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Greedy algorithms\n", + "\n", + "> Algorithms that make an optimal choice first, and then stick to it\n", + "\n", + "Examples:\n", + "\n", + "- Change-making problem\n", + "- Knapsack problem" + ] + }, + { + "cell_type": "markdown", + "id": "1464792e", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Change-making problem\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "19852a60", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Coin change (pseudo code)\n", + "\n", + "1. Sort the coins\n", + "\n", + "2. Initialize a variable to count coins used\n", + "\n", + "3. Substrack the number of coins used (if limited)\n", + "\n", + "4. Continue this process until amount becomes zero.\n" + ] + }, + { + "cell_type": "markdown", + "id": "8c5e5909", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Coin change (Python)\n", + "\n", + "_Greedy solution._" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "a5a4633a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n" + ] + } + ], + "source": [ + "def coin_change_greedy(coins, amount):\n", + " coins.sort(reverse=True) # Sort the coins in descending order\n", + " \n", + " coin_count = 0\n", + " remaining_amount = amount\n", + " \n", + " for coin in coins:\n", + " while remaining_amount >= coin:\n", + " remaining_amount -= coin\n", + " coin_count += 1\n", + " \n", + " if remaining_amount == 0:\n", + " return coin_count\n", + " else:\n", + " return -1\n", + "\n", + "coins = [1, 2, 5]\n", + "amount = 11\n", + "print(coin_change_greedy(coins, amount)) # 3 (11 = 5 + 5 + 1)" + ] + }, + { + "cell_type": "markdown", + "id": "97703194", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Huffman coding" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6372a46e", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99042d46", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5cd75ee6", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "1d7cfa02", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Dynamic programming\n", + "\n", + "> **Dynamic programming** involves breaking down a problem into subproblems, *solving* these subproblems, and *combining* their solutions to obtain the solution to the original problem. The steps are as follows:\n", + "\n", + "1. Characterize the structure of an optimal solution.\n", + "2. Define the value of an optimal solution recursively.\n", + "3. Reconstruct the optimal solution from the computations.\n", + "\n", + "Notes :\n", + "- Applies to problems with optimal substructure.\n", + "- Also applies to problems where solutions are often interrelated (distinguishing it from divide and conquer).\n", + "- Utilizes a memoization approach, involving storing an intermediate solution (e.g., in a table).\n" + ] + }, + { + "cell_type": "markdown", + "id": "d8a79a3d", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Examples of dynamic programming algorithms\n", + "\n", + "- Fibonacci Sequence\n", + "- Rod Cutting\n", + "- Shortest Path Finding\n", + "- Sequence Alignment, Longest Subsequence Finding" + ] + }, + { + "cell_type": "markdown", + "id": "bedc74a2", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Fibonnacci (reminder)\n", + "\n", + "To calculate the $n$-th number in the Fibonacci sequence, which is determined as follows:\n", + "\n", + "latex\n", + "Copy code\n", + "$fib(n) = fib(n-1) + fib(n-2)$, $n \\in \\mathbb{N}$\n", + "Where the sequence starts with 1, 1, and then continues as 2, 3, 5, 8, 13, 21, and so on, to find the 9th number ($n = 9$).\n", + "\n", + "Let's calculate the 9th Fibonacci number step by step:\n", + "\n", + "$fib(1) = 1$\n", + "\n", + "$fib(2) = 1$\n", + "\n", + "$fib(3) = fib(2) + fib(1) = 1 + 1 = 2$\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "4ccca6dd", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Fibonnacci (naive)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "57411e8e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 1, 2, 3, 5, 8, 13]\n" + ] + } + ], + "source": [ + "def fib(n):\n", + " if n < 2:\n", + " return n\n", + " else:\n", + " return fib(n - 1) + fib(n - 2)\n", + "print(list(map(fib, range(8))))" + ] + }, + { + "cell_type": "markdown", + "id": "b79f68cf", + "metadata": {}, + "source": [ + "Call tree (for $n = 6$) :" + ] + }, + { + "cell_type": "markdown", + "id": "b3bca648", + "metadata": {}, + "source": [ + "<img src=\"figures/fibonacci-tree.png\" style=\"width:400px\">" + ] + }, + { + "cell_type": "markdown", + "id": "a3a595ab", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Fibonnacci (optimized using a lookup table)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "5b1d2bb3", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Le nombre de fibonacci est 8\n" + ] + } + ], + "source": [ + "def fib(n, lookup): \n", + " \n", + " # Cas d'arrêt\n", + " if n == 0 or n == 1 : \n", + " lookup[n] = n \n", + " \n", + " # On calcule la valeur si pas déjà calculée\n", + " if lookup[n] is None: \n", + " lookup[n] = fib(n-1 , lookup) + fib(n-2 , lookup) \n", + " \n", + " # On renvoie la n-eme valeur\n", + " return lookup[n] \n", + " \n", + "def main(): \n", + " n = 6 \n", + " max = 100\n", + " # Initialise la table de cache\n", + " lookup = [None]*(max)\n", + " print(\"Le nombre de fibonacci est \", fib(n, lookup))\n", + " # Le nombre de fibonacci est 8\n", + "\n", + "if __name__==\"__main__\": \n", + " main() " + ] + }, + { + "cell_type": "markdown", + "id": "f4e93e84", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Rod cutting" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "cffad9ad", + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid non-printable character U+2000 (2415646412.py, line 2)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m Cell \u001b[0;32mIn[6], line 2\u001b[0;36m\u001b[0m\n\u001b[0;31m (3), optimale pour t = (0; 1; 1; 5) ;\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid non-printable character U+2000\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "ca5381d3", + "metadata": {}, + "outputs": [], + "source": [ + "def valeur(decoupe, t):\n", + " s = 0\n", + " for taille in decoupe:\n", + " s += t[taille]\n", + " return s" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "1f4298bc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "30" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "decoupe = [1, 2, 3, 2] # Par exemple, une découpe possible\n", + "t = [1, 5, 8, 9, 10, 17, 17, 20]\n", + "valeur(decoupe, t)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "1ac70348", + "metadata": {}, + "outputs": [], + "source": [ + "def coupe_brute_force(n, t):\n", + " if n == 0:\n", + " return 0\n", + " max_valeur = float('-inf')\n", + " for i in range(1, n + 1):\n", + " valeur_courante = t[i] + coupe_brute_force(n - i, t)\n", + " max_valeur = max(max_valeur, valeur_courante)\n", + " return max_valeur" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "82e44946", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The maximum value for a rod of length 8 is 22.\n" + ] + } + ], + "source": [ + "lengths = [0, 1, 2, 3, 4, 5, 6, 7, 8]\n", + "values = [0, 1, 5, 8, 9, 10, 17, 17, 20]\n", + "\n", + "# Length of the rod you want to cut\n", + "rod_length = 8\n", + "\n", + "# Call the brute force cutting function\n", + "max_value = coupe_brute_force(rod_length, values)\n", + "\n", + "print(f\"The maximum value for a rod of length {rod_length} is {max_value}.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35079643", + "metadata": {}, + "outputs": [], + "source": [ + "arr = [1, 5, 8, 9, 10, 17, 17, 20] " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "6387dcea", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Valeur maximum de découpe 22 8\n" + ] + } + ], + "source": [ + "INT_MIN = 0\n", + "\n", + "def cutRod(price, n): \n", + "\n", + " # Initialisation tables de cache\n", + " val = [0 for x in range(n+1)] \n", + " val[0] = 0\n", + " \n", + " for i in range(1, n+1): \n", + " max_val = INT_MIN \n", + " for j in range(i): \n", + " max_val = max(max_val, price[j] + val[i-j-1]) \n", + " val[i] = max_val \n", + " \n", + " return val[n] \n", + " \n", + "if __name__==\"__main__\": \n", + " arr = [1, 5, 8, 9, 10, 17, 17, 20] \n", + " size = len(arr) \n", + " print(\"Valeur maximum de découpe \" + str(cutRod(arr, size)), len(arr) ) " + ] + } + ], + "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/01-data-structures-complexity-exercises.ipynb b/solutions/01-data-structures-complexity-exercises.ipynb new file mode 100644 index 0000000..c365c43 --- /dev/null +++ b/solutions/01-data-structures-complexity-exercises.ipynb @@ -0,0 +1,240 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a4e4fad3", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Data Structures and Complexity" + ] + }, + { + "cell_type": "markdown", + "id": "a8adef9b", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "827ebb43-1e5d-4756-83ba-97af3e36b6af", + "metadata": {}, + "source": [ + "_For the following question, if a complexity is needed please pick one in this list_" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b54157fc-f0d5-4689-bf2b-344a608bc5a9", + "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 1: Identify the complexity" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "id": "431fe8c1-91d1-40f3-a7a4-f4a3770a4a01", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def nested_loop_example(arr):\n", + " n = len(arr)\n", + " for i in range(n):\n", + " for j in range(n):\n", + " print(arr[i] + arr[j])" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "id": "e68b3e9a-418f-4950-9f27-18bb0fe90794", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-a06bfe9af33fe998", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# nested_loop_example_complexity = ?\n", + "### BEGIN SOLUTION\n", + "nested_loop_example_complexity = \"O(n^2)\"\n", + "### END SOLUTION" + ] + }, + { + "cell_type": "markdown", + "id": "612dc873-419b-42c5-be36-0accd03ffa79", + "metadata": {}, + "source": [ + "### Exercise 2: Identify the complexity" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "id": "76102853-e1f3-4717-8a59-1091195a19eb", + "metadata": {}, + "outputs": [], + "source": [ + "def fibonacci_recursive(n):\n", + " if n <= 1:\n", + " return n\n", + " return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "id": "dead6a52-7996-4eae-9d2a-f75d5d26bbb7", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-34e130eb0c6b7e82", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# fibonacci_recursive_complexity = ?\n", + "### BEGIN SOLUTION\n", + "fibonacci_recursive_complexity = \"O(n^2)\"\n", + "### END SOLUTION" + ] + }, + { + "cell_type": "markdown", + "id": "aa4a6ce7-e542-4b23-8a10-ca0bf93de041", + "metadata": {}, + "source": [ + "### Exercise 3: Identify the complexity" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "id": "70af3e43-8053-49c9-ba58-346a3e915bdb", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def binary_search(arr, target):\n", + " low, high = 0, len(arr) - 1\n", + " while low <= high:\n", + " mid = (low + high) // 2\n", + " if arr[mid] == target:\n", + " return mid\n", + " elif arr[mid] < target:\n", + " low = mid + 1\n", + " else:\n", + " high = mid - 1\n", + " return -1" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "id": "9c22866c-b4fc-4228-b0ab-5882d964f5f6", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "cell-ea8595a5923fbb0e", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# binary_searche_complexity = ?\n", + "### BEGIN SOLUTION\n", + "binary_searche_complexity = \"O(nlog(n))\"\n", + "### END SOLUTION" + ] + }, + { + "cell_type": "markdown", + "id": "87b4921b-ef55-4083-b4f1-a3ca5bb7b011", + "metadata": {}, + "source": [ + "### Additional checks (do not change)" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "id": "6e8f2878-ce5f-4cd8-a5a5-7bce8f655ab8", + "metadata": { + "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" + ] + } + ], + "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/02-recursion-exercises.ipynb b/solutions/02-recursion-exercises.ipynb new file mode 100644 index 0000000..57912dd --- /dev/null +++ b/solutions/02-recursion-exercises.ipynb @@ -0,0 +1,1203 @@ +{ + "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": 3, + "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": 4, + "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": 5, + "id": "f6baae3c-3660-4add-ab4b-48016cba3030", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "find_maximum_iterative([1, 3, 5, 7, 9])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "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": 7, + "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": 8, + "id": "f9784710-4b2b-434c-bc47-da46fa410749", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "find_maximum_recursive([1, 3, 5, 7, 9])" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "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": 10, + "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": 11, + "id": "cec0caca-cb2c-4e4d-b004-27b3cf2ff611", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum_of_digits(10)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "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": 13, + "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": 14, + "id": "abddd3b1-f75f-4cb6-a09e-54eed489c5b0", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1024" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "power(2, 10)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "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" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "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": 17, + "id": "13acad7e-d03c-4ea6-ad86-baf02e0910eb", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'niamoR'" + ] + }, + "execution_count": 17, + "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": "code", + "execution_count": 19, + "id": "159b6d78-03ae-4cf8-8545-e822b7160b32", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def iterative_reverse_string(s):\n", + " reversed_str = \"\"\n", + " for char in s:\n", + " reversed_str = char + reversed_str\n", + " return reversed_str" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43e10b0c", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "5ab8f3c9-ddee-45ab-a013-fdd67d9853e0", + "metadata": {}, + "source": [ + "### Example 5: convert an interative suite into a recursive tail function" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "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": 21, + "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": 22, + "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": 23, + "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": 24, + "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 an annagram\n", + "\n", + "Check if a word can be read backwards." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "51bb3d08", + "metadata": { + "nbgrader": { + "grade": false, + "grade_id": "annagram_rec", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def annagram_rec(word):\n", + " ### BEGIN SOLUTION\n", + " if len(word) < 2: \n", + " return True\n", + " return (word[0] == word[-1]) and annagram_rec(word[1:len(word)-1])\n", + " ### END SOLUTION" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "0c279628-9b96-4687-8e20-a954ab646e0f", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "annagram_rec(\"laval\")" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "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 annagram_rec(\"\")\n", + "assert annagram_rec(\"AA\")\n", + "assert not annagram_rec(\"ABC\")\n", + "assert annagram_rec(\"ABA\")\n", + "assert annagram_rec(\"LAVAL\")" + ] + }, + { + "cell_type": "markdown", + "id": "798c2875-7940-488a-8458-ad08f6a71c70", + "metadata": {}, + "source": [ + "### Example 7: Calculate GCD\n" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "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": 29, + "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": 30, + "id": "4f1feace", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recursive_gcd(10, 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "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 is sorted" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "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(lst):\n", + " ### BEGIN SOLUTION\n", + " if len(lst) <= 1:\n", + " return True\n", + " else:\n", + " return lst[0] <= lst[1] and is_sorted(lst[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": 34, + "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])" + ] + }, + { + "cell_type": "markdown", + "id": "79eef392-1d3d-46c0-aeee-ac805686e6f1", + "metadata": {}, + "source": [ + "### Example 9: Check for prime number" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "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": 36, + "id": "996fc91f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "is_prime_recursive(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "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": 38, + "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(arr, target, index=0):\n", + " ### BEGIN SOLUTION\n", + " if index == len(arr):\n", + " return 0\n", + " \n", + " count = (1 if arr[index] == target else 0)\n", + " \n", + " return count + count_occurrences(arr, target, index + 1)\n", + " ### END SOLUTION" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "49daec07-00b3-412e-ad44-5bafadbd9f36", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "count_occurrences([1, 2, 3, 4, 2, 2, 5, 6, 2], 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "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 points" + ] + }, + { + "cell_type": "markdown", + "id": "7fdcd705-dc0b-4614-8e27-9ba62f8fe442", + "metadata": {}, + "source": [ + "### Exercise 1: 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 1: 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": 45, + "id": "b8bc657e-d491-4851-aa8c-ac2f2eac0841", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 66, + "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)]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d601b2f3-c33b-4ed2-81be-639ce1ffab76", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f252530-7817-444c-ae10-d7b3bca87f2d", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0976f7c2-4375-4d76-a6c1-9e729a6c8aeb", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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 +} -- GitLab