{ "cells": [ { "cell_type": "code", "execution_count": 10, "id": "41bed2c0", "metadata": {}, "outputs": [], "source": [ "import math" ] }, { "cell_type": "markdown", "id": "6c5721d4", "metadata": {}, "source": [ "# Aproximación para $\\ln(x)$\n", "El logaritmo natural de $(1 + x)$ puede aproximarse mediante la serie de Maclaurin (serie de Taylor para $\\ln(1 + x)$ centrada en 0):\n", "\n", "$$\n", "\\ln(1 + x) = \\sum_{n=1}^{\\infty} \\frac{(-1)^{n+1} \\cdot x^n}{n} = x - \\frac{x^2}{2} + \\frac{x^3}{3} - \\frac{x^4}{4} + \\cdots \\quad \\text{(válido para } -1 < x \\leq 1\\text{)}\n", "$$\n", "\n", "- Implementar en Python una función que calcule esta aproximación para un valor $x$ (en el rango $(-1, 1]$) y un número de términos $N$.\n", "- Comparar el resultado con el valor real de $\\ln(1 + x)$ (usando $\\texttt{math.log(1 + x)}$).\n" ] }, { "cell_type": "code", "execution_count": 11, "id": "1a068ce1", "metadata": {}, "outputs": [], "source": [ "def approx_ln(x,N):\n", " if x<=-1 and x>=1:\n", " return None\n", " suma=0\n", " for n in range(1,N):\n", " suma+=(-1)**(n+1)*(x**n)/n\n", " return suma" ] }, { "cell_type": "code", "execution_count": 12, "id": "5343443b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Aproximación de ln(1 + 0.5) con 10 términos: 0.4055323040674603\n", "Valor real de ln(1 + 0.5): 0.4054651081081644\n", "Diferencia: 6.719595929594036e-05\n" ] } ], "source": [ "# Ejemplo de uso\n", "x = 0.5 # Debe estar en (-1, 1]\n", "N = 10\n", "aprox_ln = approx_ln(x, N)\n", "real_ln = math.log(1 + x)\n", "\n", "print(f\"Aproximación de ln(1 + {x}) con {N} términos: {aprox_ln}\")\n", "print(f\"Valor real de ln(1 + {x}): {real_ln}\")\n", "print(f\"Diferencia: {abs(real_ln - aprox_ln)}\")" ] }, { "cell_type": "markdown", "id": "ab6ce2dd", "metadata": {}, "source": [ "# Números amigos en un rango dado\n", "\n", "Dos números naturales $a$ y $b$ se llaman **números amigos** si la suma de los divisores propios (excluyendo el número mismo) de $a$ es igual a $b$, y viceversa.\n", "\n", "Por ejemplo, 220 y 284 son números amigos porque:\n", "- Los divisores propios de 220 son: 1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110 → suma: 284\n", "- Los divisores propios de 284 son: 1, 2, 4, 71, 142 → suma: 220\n", "\n", "Escribe un programa que encuentre todos los pares de números amigos en un rango dado (por ejemplo, entre 1 y 10000)." ] }, { "cell_type": "code", "execution_count": 13, "id": "4b8c6984", "metadata": {}, "outputs": [], "source": [ "def suma_divisores_propios(n):\n", " \"\"\"Calcula la suma de los divisores propios de un número (excluyendo al mismo número)\"\"\"\n", " if n == 1:\n", " return 0\n", " suma = 1 # 1 es divisor propio para todos los números > 1\n", " for i in range(2, n-1):\n", " if n % i == 0:\n", " suma += i\n", " return suma" ] }, { "cell_type": "code", "execution_count": 14, "id": "c804c52a", "metadata": {}, "outputs": [], "source": [ "def encontrar_numeros_amigos(limite_inferior, limite_superior):\n", " \"\"\"Encuentra todos los pares de números amigos dentro del rango especificado\"\"\"\n", " pares_amigos = set() \n", " \n", " for a in range(limite_inferior, limite_superior + 1):\n", " b = suma_divisores_propios(a)\n", " \n", " # Verificamos si b está en el rango y si la suma de divisores de b es igual a a\n", " if (limite_inferior <= b <= limite_superior and suma_divisores_propios(b) == a):\n", " pares_amigos.add((a, b))\n", " \n", " return sorted(pares_amigos)" ] }, { "cell_type": "code", "execution_count": 15, "id": "6d89c508", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Buscador de números amigos\n", "\n", "Pares de números amigos encontrados:\n", "6 y 6\n", "28 y 28\n", "220 y 284\n", "284 y 220\n", "496 y 496\n", "1184 y 1210\n", "1210 y 1184\n", "2620 y 2924\n", "2924 y 2620\n", "5020 y 5564\n", "5564 y 5020\n", "6232 y 6368\n", "6368 y 6232\n", "8128 y 8128\n" ] } ], "source": [ "# Definir el rango \n", "print(\"Buscador de números amigos\")\n", "lim_inf = 1\n", "lim_sup=10000\n", "\n", "# Encontrar y mostrar los pares de números amigos\n", "pares = encontrar_numeros_amigos(lim_inf, lim_sup)\n", "\n", "if pares:\n", " print(\"\\nPares de números amigos encontrados:\")\n", " for par in pares:\n", " print(f\"{par[0]} y {par[1]}\")\n", "else:\n", " print(\"\\nNo se encontraron pares de números amigos en el rango especificado.\")" ] }, { "cell_type": "markdown", "id": "62014a68", "metadata": {}, "source": [ "## Actividad:\n", "- Vemos que estamos obteniendo números duplicados. ¿Qué se puede hacer para evitar esto?" ] }, { "cell_type": "markdown", "id": "245ebef9", "metadata": {}, "source": [ "## Una solución:" ] }, { "cell_type": "code", "execution_count": null, "id": "18a8014f", "metadata": {}, "outputs": [], "source": [ "def encontrar_numeros_amigos(limite_inferior, limite_superior):\n", " \"\"\"Encuentra todos los pares de números amigos dentro del rango especificado\"\"\"\n", " pares_amigos = set() \n", " \n", " for a in range(limite_inferior, limite_superior + 1):\n", " b = suma_divisores_propios(a)\n", " \n", " # Verificamos si b está en el rango, si la suma de divisores de b es igual a a y si b es mayor que a\n", " if (limite_inferior <= b <= limite_superior and suma_divisores_propios(b) == a and b>a):\n", " pares_amigos.add((a, b))\n", " \n", " return sorted(pares_amigos)" ] }, { "cell_type": "code", "execution_count": 17, "id": "ae7a4e91", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Buscador de números amigos\n", "\n", "Pares de números amigos encontrados:\n", "220 y 284\n", "1184 y 1210\n", "2620 y 2924\n", "5020 y 5564\n", "6232 y 6368\n" ] } ], "source": [ "# Definir el rango \n", "print(\"Buscador de números amigos\")\n", "lim_inf = 1\n", "lim_sup=10000\n", "\n", "# Encontrar y mostrar los pares de números amigos\n", "pares = encontrar_numeros_amigos(lim_inf, lim_sup)\n", "\n", "if pares:\n", " print(\"\\nPares de números amigos encontrados:\")\n", " for par in pares:\n", " print(f\"{par[0]} y {par[1]}\")\n", "else:\n", " print(\"\\nNo se encontraron pares de números amigos en el rango especificado.\")" ] }, { "cell_type": "markdown", "id": "7490b240", "metadata": {}, "source": [ "## Reto:\n", "- ¿Alguna forma de reducir el tiempo de código?\n", "Pista: La función `suma_divisores_propios` se puede optimizar" ] }, { "cell_type": "markdown", "id": "91a876f5", "metadata": {}, "source": [ "## Una forma (se puede optimizar más)" ] }, { "cell_type": "code", "execution_count": 18, "id": "f2d911f9", "metadata": {}, "outputs": [], "source": [ "def suma_divisores_propios(n):\n", " \"\"\"Calcula la suma de los divisores propios de un número (excluyendo al mismo número)\"\"\"\n", " if n == 1:\n", " return 0\n", " suma = 1 # 1 es divisor propio para todos los números > 1\n", " for i in range(2, int(n/2)+1):\n", " if n % i == 0:\n", " suma += i\n", " return suma" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.6" } }, "nbformat": 4, "nbformat_minor": 5 }