{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "fibonacci.ipynb",
      "provenance": [],
      "authorship_tag": "ABX9TyOqX1CHs91z5hPoJct/n7GQ",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/financieras/altocodigoPy/blob/main/fibonacci.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Fibonacci\n",
        "* La [sucesión de Fibonacci](https://es.wikipedia.org/wiki/Sucesi%C3%B3n_de_Fibonacci) comienza con los dos primeros valores que son 0 y 1.\n",
        "* El resto de los términos se obtiene sumando los dos anteriores.\n",
        "* 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, ..."
      ],
      "metadata": {
        "id": "TFJdJWFFtjoy"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Método 1\n",
        "* Solicitamos al usuario que nos indique el número de elementos de la sucesión que desea generar.\n",
        "* Establecemos en 5 el número mínimo de elementos a mostrar.\n",
        "* Usamos la función ```max``` para que si el usuario nos proporciona un número menor a 5, se establezca n igual a 5."
      ],
      "metadata": {
        "id": "eR85A98btpad"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "n = max(int(input('¿Cuántos valores quieres? (minimo 5): ')), 5)\n",
        "a = 0\n",
        "b = 1\n",
        "print(a)\n",
        "print(b)\n",
        "for i in range(0, n-2):\n",
        "    aux = a + b   # usamos una variable auxiliar para obtener el siguiente valor de la serie\n",
        "    print(aux)\n",
        "    a = b\n",
        "    b = aux"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ayFEfP2e3Ql9",
        "outputId": "10650265-a39d-46a0-eeac-1f838b1f94aa"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "¿Cuántos valores quieres? (minimo 5): 20\n",
            "0\n",
            "1\n",
            "1\n",
            "2\n",
            "3\n",
            "5\n",
            "8\n",
            "13\n",
            "21\n",
            "34\n",
            "55\n",
            "89\n",
            "144\n",
            "233\n",
            "377\n",
            "610\n",
            "987\n",
            "1597\n",
            "2584\n",
            "4181\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Método 2\n",
        "* Con una estructura ```while True``` solicitamos el valor de n, que se continuará preguntando hasta que el usuario introduzca un valor mayor que dos.\n",
        "* Trabajamos con listas donde los dos primeros elementos vienen dados y son 0 y 1.\n",
        "* Los restantes elementos se generan sumando los dos previos y se añaden a la lista con ```append```."
      ],
      "metadata": {
        "id": "FW2eWvIKuE9T"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "while True:\n",
        "    n=int(input('¿Cuántos valores quieres? (mínimo 3): '))\n",
        "    if n > 2:\n",
        "        break\n",
        "x = [0,1]\n",
        "for i in range(n-2):\n",
        "    x.append(x[-1] + x[-2])\n",
        "print(x)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "6xsXX2XjuIxu",
        "outputId": "b56d3f56-6b1c-4fcf-f893-9de2a0e2c9e7"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "¿Cuántos valores quieres? (mínimo 3): 20\n",
            "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Método 3\n",
        "* Trabajamos con una lista que inicializamos con los dos primeros valores 0 y 1.\n",
        "* Nos metemos en un bucle ```for``` dentro del cual usamos ```append``` para ir añadiendo elementos nuevos a la sucesión de Fibonacci."
      ],
      "metadata": {
        "id": "xElJwEHNudjP"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "lista = [0, 1]\n",
        "for i in range(3, 21):\n",
        "    lista.append(lista[len(lista)-1] + lista[len(lista)-2])\n",
        "print(lista)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "94rOkKrdugnm",
        "outputId": "3f21cabd-305c-4879-cb18-f0b71569a792"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Método 4\n",
        "* Trabajamos con una función dentro de la cual inicializamos las variables a y b con los valores 0 y 1 respectivamente.\n",
        "* Nos metemos en un bucle ```for``` donde creamos una tercera variable auxiliar c que será la suma de a+b."
      ],
      "metadata": {
        "id": "FXouW5a1uv8w"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def fibo(n):\n",
        "    a, b = 0, 1\n",
        "    for i in range(3, n+1):\n",
        "        c = a + b\n",
        "        a = b\n",
        "        b = c\n",
        "    return(c)\n",
        "print(fibo(100))"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "3Snrb-gGuyJK",
        "outputId": "af78a8ef-7282-4e41-a983-bd9ada5dfc05"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "218922995834555169026\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Método 5\n",
        "Trabajamos con una lista llamada fibo que vamos alimentando con ```append``` a cada ciclo de bucle ```for```."
      ],
      "metadata": {
        "id": "FKI849wOvDaO"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "n = 20    # número de términos de la serie\n",
        "fibo = [0, 1]\n",
        "for i in range (n-2):\n",
        "    fibo.append(fibo[-1] + fibo[-2])\n",
        "print(fibo)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "mcJF6ASMvGeT",
        "outputId": "b6f9ef79-29f6-475b-c1e3-c49c45dbe036"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Método 6\n",
        "* Creamos una función a la que pasamos el parámetro n que nos indica el número de elementos de la sucesión de Fibonacci que deseamos.\n",
        "* Dentro de la función definimos las variables a y b con los valores 0 y 1 respectivamente.\n",
        "* Nos metemos en un bucle ```for``` que recorrerá los elementos que vamos a generar.`\n",
        "* Se imprime el valor de a y se deja un espacio vacío, evitando el retorno de carro.\n",
        "* Asignamos a la variable a el valor de b, y a la b el valor de a+b.\n",
        "* La última línea de código dentro de la función es un ```print()``` que equivale a un retorno de carro, pero permite imprimir el resultado."
      ],
      "metadata": {
        "id": "YTV1NNxEwbEr"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def fibo(n):\n",
        "    a, b = 0, 1\n",
        "    for i in range(n):\n",
        "        print(a, end=' ')\n",
        "        a, b = b, a+b\n",
        "    print()\n",
        "fibo(20)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "cEjflIj7wdnS",
        "outputId": "e7492b28-b537-4fe9-c37c-59f2bdda7006"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 \n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Método 7\n",
        "* Si te has preguntado cómo conseguir la sucesión de Fibonacci sin usar una variable auxiliar aquí tienes la solución.\n",
        "* Con este método evitamos tener que utilizar una variable auxiliar."
      ],
      "metadata": {
        "id": "aDa6ho03xFQQ"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "n = 20\n",
        "a, b = 0, 1\n",
        "print(\"1:\", a)\n",
        "print(\"2:\", b)\n",
        "\n",
        "for i in range(3, n+1):\n",
        "    b = a + b\n",
        "    a = b - a  # así evitamos emplear una variable auxiliar\n",
        "    print(f\"{i}: {b}\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "PrPfVbCOxJT0",
        "outputId": "01e20c6d-2377-4ff6-c75f-d28510055950"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1: 0\n",
            "2: 1\n",
            "3: 1\n",
            "4: 2\n",
            "5: 3\n",
            "6: 5\n",
            "7: 8\n",
            "8: 13\n",
            "9: 21\n",
            "10: 34\n",
            "11: 55\n",
            "12: 89\n",
            "13: 144\n",
            "14: 233\n",
            "15: 377\n",
            "16: 610\n",
            "17: 987\n",
            "18: 1597\n",
            "19: 2584\n",
            "20: 4181\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Método 8\n",
        "* Por recursión\n",
        "* Usando la recursividad\n",
        "* Es importante establecer la condición de parada.\n",
        "* La **condición de parada**, cuando es cierta, permite resolver el algoritmo directamente.\n",
        "* La **llamada recursiva** permite resolver el problema cuando la resolución no es directa.\n",
        "* La función se va llamando a si misma hasta que se llega al final que es la condición de parada\n",
        "* La regla recursiva viene dada por la siguiente expresión.\n",
        "\n",
        "$$fibonacci(n) = \\left\\lbrace\\begin{array}{c} 0~& si~n=1 \\\\ 1~& si~n=2 \\\\\n",
        "fibonacci(n-1) + fibonacci(n-2) ~& si~n>2 \\end{array}\\right.$$"
      ],
      "metadata": {
        "id": "OC_97W2QMof5"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def fibo(n):\n",
        "    if n <= 1:                          # condición de parada o \"caso base\"\n",
        "        return n\n",
        "    else:\n",
        "        return(fibo(n-1) + fibo(n-2))   # \"caso recursivo\"\n",
        "\n",
        "n = 20\n",
        "\n",
        "for i in range(n):                     # i va de 0 a n-1\n",
        "    print(f\"{i+1} → {fibo(i)}\")"
      ],
      "metadata": {
        "id": "Ch5KKjjXM14T",
        "outputId": "a91233c7-210a-4de4-cce2-5bb130b96e0e",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1 → 0\n",
            "2 → 1\n",
            "3 → 1\n",
            "4 → 2\n",
            "5 → 3\n",
            "6 → 5\n",
            "7 → 8\n",
            "8 → 13\n",
            "9 → 21\n",
            "10 → 34\n",
            "11 → 55\n",
            "12 → 89\n",
            "13 → 144\n",
            "14 → 233\n",
            "15 → 377\n",
            "16 → 610\n",
            "17 → 987\n",
            "18 → 1597\n",
            "19 → 2584\n",
            "20 → 4181\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Método 9\n",
        "* Una variante del caso anterior\n",
        "* Usando también la recursividad"
      ],
      "metadata": {
        "id": "RIOyh1vWVZTx"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def fibo(n):\n",
        "    if n in {0, 1}:\n",
        "        return n\n",
        "    return fibo(n-1) + fibo(n-2)\n",
        "\n",
        "n = 19\n",
        "\n",
        "[fibo(i) for i in range(n)]"
      ],
      "metadata": {
        "id": "iQmbdHGqVj6L",
        "outputId": "7a8cf351-cab6-4101-b198-ddc1a6fbe76d",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]"
            ]
          },
          "metadata": {},
          "execution_count": 22
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Método 10\n",
        "Elegancia con un ```while```."
      ],
      "metadata": {
        "id": "2FdTAPYs6su-"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "a, b = 0, 1\n",
        "while a < 100:\n",
        "    print(a)\n",
        "    a, b = b, a+b"
      ],
      "metadata": {
        "id": "c3uJuxP563x3",
        "outputId": "08a3d86b-b788-40bd-e394-e783f12b8edc",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0\n",
            "1\n",
            "1\n",
            "2\n",
            "3\n",
            "5\n",
            "8\n",
            "13\n",
            "21\n",
            "34\n",
            "55\n",
            "89\n"
          ]
        }
      ]
    }
  ]
}