{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "starting-portfolio",
   "metadata": {},
   "source": [
    "# Recursion"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "further-brighton",
   "metadata": {},
   "source": [
    "A recursive algorithm is an algorithm that calls itself. You need a base case so you don't get stuck in an infinite loop."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "sunrise-cyprus",
   "metadata": {},
   "source": [
    "Example: suppose we want to calculate the quantity $n! = n(n-1)(n-2)\\cdots 3 \\cdot 2 \\cdot 1$."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18459a42",
   "metadata": {},
   "source": [
    "5! = 5 * 4 * 3 * 2 * 1 = 120"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "gorgeous-girlfriend",
   "metadata": {},
   "source": [
    "We'll use the fact that $n! = n \\cdot (n-1)!$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "metallic-psychiatry",
   "metadata": {},
   "outputs": [],
   "source": [
    "# What's wrong with this function?\n",
    "def factorial(n):\n",
    "    return n * factorial(n-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "appropriate-moore",
   "metadata": {},
   "outputs": [],
   "source": [
    "factorial(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "31f6174b",
   "metadata": {},
   "source": [
    "What calls are happening?\n",
    "```py\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dbbe172d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# What's wrong with this function?\n",
    "def factorial(n):\n",
    "    return n * factorial(n-1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ba3a205",
   "metadata": {},
   "source": [
    "```py\n",
    "factorial(3)\n",
    " -> 3 * factorial(2)\n",
    " -> 3 * 2 * factorial(1)\n",
    " -> 3 * 2 * 1 * factorial(0)\n",
    " -> 3 * 2 * 1 * 0 * factorial(-1)\n",
    " -> infinite recursion\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "failing-lounge",
   "metadata": {},
   "outputs": [],
   "source": [
    "# We need a base case!\n",
    "def factorial(n):\n",
    "    assert n >= 0 and isinstance(n, int), \"invalid input into factorial\"\n",
    "    if n == 1:\n",
    "        # factorial(1) = 1\n",
    "        return 1\n",
    "    return n * factorial(n-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d7de0b92-3cce-43b5-9d68-a35a01777497",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "acute-delicious",
   "metadata": {},
   "outputs": [],
   "source": [
    "factorial(3.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "698c2503-e632-41d5-8857-6d55af9cb1c6",
   "metadata": {},
   "outputs": [],
   "source": [
    "factorial(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "municipal-phoenix",
   "metadata": {},
   "source": [
    "```py\n",
    "factorial(5)\n",
    "5 * factorial(4)\n",
    "5 * (4 * factorial(3))\n",
    "5 * (4 * (3 * factorial(2)))\n",
    "5 * (4 * (3 * (2 * factorial(1))))\n",
    "5 * (4 * (3 * (2 * 1)))\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "functional-pointer",
   "metadata": {},
   "outputs": [],
   "source": [
    "factorial(-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "chinese-applicant",
   "metadata": {},
   "outputs": [],
   "source": [
    "factorial(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f8e7a6d4-baca-47a5-91d3-f607ac866698",
   "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.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
