Podcast sobre Algoritmos, Estructuras y Paradigmas de Programación

Algoritmos, Estructuras y Paradigmas de Programación: Guía SEO

Podcast

Algoritmos y Paradigmas: El Lenguaje Secreto de las Computadoras0:00 / 24:11
0:001:00 restante
Mateo…entonces, ¡la forma en que mi teléfono organiza miles de fotos en un instante es pura matemática!
Carmen¡Exacto, Mateo! No es magia, es la elegancia de un buen algoritmo trabajando. Es la columna vertebral de casi todo lo que usamos hoy en día.
Capítulos

Algoritmos y Paradigmas: El Lenguaje Secreto de las Computadoras

Délka: 24 minut

Kapitoly

La Magia de los Algoritmos

Los Idiomas del Código

La Búsqueda Comienza

Búsqueda Lineal: Paso a Paso

Búsqueda Binaria: El Súper Poder

Lineal vs. Binaria: La Decisión Final

El eco en el código

Buscando en el laberinto

El clásico: Factorial

Una máquina de jugos

Inmutabilidad y superpoderes

La magia de map, filter y reduce

¿El Mejor Paradigma?

La Revolución de los Objetos

Dos Caminos, Un Destino

El Eco de la Recursión

La Notación Big O

Tiempo vs. Espacio

Estrategias de Optimización

Ponlo a Prueba

Pilares Fundamentales

La Magia del Polimorfismo

Resumen y Despedida

Přepis

Mateo: …entonces, ¡la forma en que mi teléfono organiza miles de fotos en un instante es pura matemática!

Carmen: ¡Exacto, Mateo! No es magia, es la elegancia de un buen algoritmo trabajando. Es la columna vertebral de casi todo lo que usamos hoy en día.

Mateo: Me vuela la cabeza. Para quienes recién se conectan, están escuchando Studyfi Podcast. Hoy, desmitificamos los algoritmos y paradigmas.

Carmen: Y es que entenderlos es crucial. Piensa en ellos como las recetas maestras que le dicen a la computadora cómo ordenar datos eficientemente o cómo encontrar información específica al instante.

Mateo: Y me encantó tu analogía sobre los paradigmas como si fueran diferentes "idiomas" para pensar.

Carmen: ¡Es que lo son! Por ejemplo, el paradigma imperativo es súper directo. Le das a la computadora una lista de instrucciones, paso a paso.

Mateo: Como una receta de cocina, ¿no? "Paso 1: corta la cebolla. Paso 2: calienta el aceite".

Carmen: ¡Exactamente! Pero luego tienes el paradigma declarativo, donde simplemente le dices el resultado que quieres: "Quiero una sopa de cebolla". No le explicas el cómo.

Mateo: ¿Y la computadora simplemente… lo resuelve? Suena a que le gusta improvisar.

Carmen: Más o menos. Se encarga de los detalles. Y luego está la programación orientada a objetos, que fue una revolución. Permitió modelar cosas del mundo real, como un coche o una persona, directamente en el código.

Mateo: Fascinante. Entender cuándo usar cada "idioma" parece ser la habilidad clave aquí.

Carmen: Totalmente. Es lo que diferencia a un programador promedio de uno genial. Ahora, hablemos de cómo estos algoritmos necesitan organizar la información...

Mateo: Ok, entonces tener los datos ordenados es súper útil. Pero, una vez que están en orden... ¿cómo encontramos lo que buscamos?

Carmen: ¡Exacto! Ese es el siguiente paso lógico. Y para eso, tenemos los algoritmos de búsqueda. Son como el GPS para nuestros datos.

Mateo: Me gusta esa analogía. ¿Por dónde empezamos? ¿Cuál es el más... básico?

Carmen: Empecemos por el más intuitivo de todos: la búsqueda lineal. A veces también se le llama búsqueda secuencial.

Mateo: Búsqueda lineal. Suena bastante directo. ¿Simplemente revisa uno por uno?

Carmen: Precisamente eso. Piensa que tienes una lista de números, como . Si buscas el número 8, el algoritmo empieza por el 2 y pregunta: "¿Eres el 8? No". Luego va al 4: "¿Tú? Tampoco". Y así, hasta que llega al 8 y grita: "¡Te encontré!".

Mateo: ¡Fácil! Y su principal ventaja debe ser que no le importa si la lista está ordenada o no, ¿verdad? Puede buscar en cualquier desorden.

Carmen: Exacto. Esa es su gran fortaleza. No necesita ninguna preparación. La desventaja, claro, es el tiempo. Si el número que buscas está al final, o si no está, tienes que recorrer toda la lista.

Mateo: Claro, eso se conoce como complejidad O(n), ¿cierto? El tiempo que tarda es proporcional al número de elementos.

Carmen: ¡Muy bien, Mateo! Para listas pequeñas, no hay problema. Pero si tienes un millón de elementos... bueno, podrías ir a prepararte un café mientras busca.

Mateo: Definitivamente no queremos eso. Entonces, ¿cuál es la alternativa rápida y furiosa?

Carmen: La búsqueda binaria. Pero aquí está el truco... solo funciona con listas que ya están ordenadas. Es el premio que recibes por haber hecho el trabajo de ordenar primero.

Mateo: Entendido. ¿Y cómo funciona este súper método?

Carmen: Es brillante. En lugar de empezar por el principio, va directo a la mitad de la lista. Si el número de en medio es el que buscas, ¡genial, terminaste!

Mateo: ¿Y si no lo es?

Carmen: Aquí viene la magia. Compara el número que buscas con el del medio. Si tu número es más grande, sabe que tiene que estar en la mitad derecha de la lista, así que... ¡descarta por completo la mitad izquierda!

Mateo: ¡Wow! Acaba de reducir el problema a la mitad con una sola comparación. Eso es increíblemente eficiente.

Carmen: Totalmente. Y repite el proceso. Va a la mitad de la sección que queda, compara y vuelve a descartar la mitad. Es como buscar una palabra en un diccionario. No empiezas en la letra A, ¿verdad? Abres por la mitad.

Mateo: La analogía del diccionario es perfecta. Entonces, la búsqueda binaria tiene una complejidad de O(log n), que es muchísimo más rápida.

Carmen: Infinitamente más rápida para listas grandes. Para ese millón de elementos que mencionamos, la búsqueda lineal podría necesitar un millón de pasos. La búsqueda binaria... necesitaría como máximo unos 20. Una locura.

Mateo: Veinte pasos contra un millón. La diferencia es abismal. Entonces, para resumir... ¿cuándo elegimos cada una?

Carmen: Es una decisión clave. Si tus datos están desordenados o la lista es muy pequeña, la búsqueda lineal es simple y efectiva. No te compliques.

Mateo: Pero... si tienes una base de datos enorme que consultas constantemente, vale la pena el esfuerzo de mantenerla ordenada para poder usar la velocidad de la búsqueda binaria.

Carmen: Diste en el clavo. Es el clásico balance entre preparación y ejecución. La búsqueda binaria necesita preparación, pero su ejecución es espectacularmente rápida.

Mateo: Fantástico. Esto aclara muchísimo el panorama sobre cómo encontrar información de forma eficiente. Ahora que sabemos ordenar y buscar, me pregunto qué otras estructuras de datos nos pueden ayudar a ser aún más eficientes...

Mateo: Y hablando de ese enfoque de «divide y vencerás», esto nos lleva directamente a un concepto que suena a película de ciencia ficción... la recursividad.

Carmen: Totalmente. Pero es más sencillo de lo que parece. Piensa en una función normal, como saludar(). La llamas y hace su trabajo, ¿cierto?

Mateo: Claro, te saluda y listo.

Carmen: Exacto. Ahora, imagina una función que, para resolver un problema, se llama a sí misma. Eso es la recursividad. Es como un eco... una función que se repite a sí misma pero cada vez con una tarea un poquito más pequeña.

Mateo: Ok, mi cerebro ya está haciendo bucles. ¿Cómo evita llamarse a sí misma para siempre?

Carmen: ¡Esa es la pregunta clave! Toda función recursiva necesita dos cosas. Primero, un «caso base». Es la condición de parada, el momento en que el problema es tan simple que se resuelve directamente.

Mateo: El momento en que el eco se detiene.

Carmen: Justo. Y segundo, el «caso recursivo». Aquí es donde la función se llama a sí misma, pero con una versión más pequeña del problema original.

Mateo: A ver, dame un ejemplo práctico. ¿Dónde usaríamos algo así?

Carmen: ¡Perfecto! Imagina que buscas un archivo en tu computadora. Tienes una carpeta principal, y dentro hay más carpetas, y dentro de esas, más carpetas...

Mateo: La historia de mi vida. Nunca encuentro nada.

Carmen: ¡Pues la recursividad te salvaría! Podrías crear una función que haga esto: primero, mira si el archivo está en la carpeta actual. Ese podría ser un caso base.

Mateo: Ok, lo encontré, ¡fin!

Carmen: Exacto. Pero si no está, la función recorre cada subcarpeta y se llama a sí misma para buscar ahí dentro. Ese es el caso recursivo. Se repite hasta que encuentra el archivo o se queda sin carpetas que revisar.

Mateo: ¡Ah! Por eso es tan potente. No necesitas saber cuántos niveles de carpetas hay de antemano. La función simplemente sigue adelante hasta que termina.

Carmen: Correcto. Y el ejemplo clásico para enseñar esto es el factorial de un número. ¿Recuerdas qué es?

Mateo: Sí, el factorial de 4, o 4!, es 4 por 3 por 2 por 1. O sea, 24.

Carmen: ¡Perfecto! Podemos definirlo recursivamente. El caso base es que el factorial de 0 es 1. El caso recursivo es que el factorial de cualquier otro número 'n' es n por el factorial de n-1.

Mateo: Entonces, para calcular el factorial de 4, la función llamaría al de 3... que a su vez llama al de 2... y así hasta llegar a 0.

Carmen: ¡Lo tienes! Cuando llega a 0, devuelve 1. Luego, esa respuesta vuelve hacia atrás, resolviendo cada llamada pendiente: 1 por 1, luego 2 por 1, 3 por 2, y finalmente 4 por 6, que da 24. Así se construye la solución final.

Mateo: Increíble. Es como dejar un rastro de migas de pan y luego seguirlas de vuelta. Es una forma de pensar muy potente... y me imagino que se puede combinar con otras herramientas, como esas funciones rápidas de las que me hablaste antes.

Mateo: ...así que los paradigmas realmente cambian la forma en que piensas sobre el código. Y me han dicho que el siguiente, el paradigma funcional, es... un mundo completamente diferente.

Carmen: ¡Totalmente! Es un cambio de mentalidad. La programación funcional trata la computación como si fueran matemáticas. Piensa en una función matemática: si le das un 2, siempre te devuelve un 4. No depende de nada más.

Mateo: ¿Y eso qué significa en código?

Carmen: Significa que no hay «efectos secundarios». Una función solo toma unas entradas y produce una salida. Siempre la misma salida para las mismas entradas. Es predecible y puro.

Mateo: Suena un poco abstracto. ¿Tienes alguna analogía para nosotros?

Carmen: ¡Claro! Piensa en una exprimidora de jugos. Le metes naranjas, que son los parámetros, y siempre te devuelve jugo de naranja, que es el resultado. No cambia el color de la cocina ni le avisa al vecino. Solo hace su trabajo.

Mateo: Me gusta. ¡Una máquina que solo hace una cosa y la hace bien! Ahora tengo hambre... y sed.

Carmen: Exacto. Esa es la esencia. Cada función es una pequeña máquina predecible y reutilizable.

Mateo: Vale, pero he oído algo que me explota la cabeza: la inmutabilidad. ¿Significa que los datos no pueden cambiar nunca?

Carmen: ¡Eso es! Una vez que creas un dato, no se puede modificar. Si quieres un cambio, en realidad creas un dato *nuevo* con ese cambio.

Mateo: Wow. Eso elimina un montón de errores, ¿no? Cuando algo cambia inesperadamente.

Carmen: Justo. Y aquí viene el superpoder: las funciones son «ciudadanos de primera clase».

Mateo: ¿Cómo que ciudadanos de primera clase? ¿Tienen pasaporte?

Carmen: Casi. Significa que puedes tratarlas como cualquier otro valor. Puedes guardarlas en variables, pasarlas como argumento a otra función o incluso hacer que una función devuelva otra función.

Mateo: Ok, ¿y cómo se usa todo esto en la práctica?

Carmen: Aquí viene la magia. Imagina que quieres la suma de los cuadrados de los números pares de una lista. En el estilo tradicional, usarías un bucle, una variable que va cambiando...

Mateo: El típico bucle for, sí.

Carmen: Pues en funcional, encadenas funciones. Primero, usas filter para quedarte solo con los pares. Luego, map para transformar cada número en su cuadrado. Y finalmente, reduce para sumarlos todos.

Mateo: ¡Vaya! Es como una línea de ensamblaje para datos. Mucho más claro.

Carmen: ¡Exactamente! Describes *qué* quieres hacer, no los pasos detallados de *cómo* hacerlo. Es increíblemente expresivo y nos lleva directamente a una idea muy relacionada con este flujo de datos...

Mateo: Okey, entonces ya tenemos claro qué es un paradigma. Pero ahora viene lo bueno... ¿cuáles son los grandes modelos que existen?

Carmen: ¡Exacto! Y para empezar, vamos a ver los dos pilares: el imperativo y el declarativo. Piensa en ellos como dos formas totalmente opuestas de dar instrucciones.

Mateo: ¿Opuestas? ¿Cómo de opuestas?

Carmen: Pues mira, el paradigma imperativo es el más antiguo. Es como darle a la computadora una receta de cocina, paso a paso. Le dices exactamente *cómo* hacer las cosas.

Mateo: Ah, ¡entiendo! Primero, inicializa una variable en cero. Segundo, recorre esta lista. Tercero, suma cada número... ¡Literalmente le das órdenes!

Carmen: ¡Justo eso! De ahí viene su nombre, del modo imperativo. La clave aquí es el "estado", que son los valores de tus variables en cada momento. Cada instrucción cambia ese estado.

Mateo: Vale, el enfoque del "cómo". ¿Y el otro? ¿El declarativo?

Carmen: El declarativo es... mágico. En lugar del "cómo", te centras en el "qué". No le das la receta, solo le muestras una foto del pastel terminado y le dices: "quiero esto".

Mateo: Espera, ¿cómo funciona eso? ¿Simplemente le pides el resultado y ya? Suena demasiado fácil.

Carmen: Bueno, casi. En vez de un bucle para sumar números, le darías la fórmula matemática directamente. Describes el resultado que quieres, y dejas que el lenguaje se encargue de los detalles.

Mateo: Entonces... ¿cuál es mejor? ¿El que da órdenes o el que pide deseos?

Carmen: ¡Buena pregunta! Pero no se trata de que uno sea mejor. Es como tener un martillo y un destornillador, cada uno sirve para algo distinto.

Mateo: A ver, explícame. ¿Cuándo usaría cada uno?

Carmen: El imperativo te da mucho control porque estás muy cerca de cómo funciona la máquina. Puede ser más eficiente... pero también es más fácil cometer errores.

Mateo: Porque tienes que gestionar todos los pequeños detalles, ¿no?

Carmen: Exacto. En cambio, el declarativo es más abstracto. Es más conciso y seguro, porque no manejas el estado directamente. Piensa en las interfaces de usuario.

Mateo: ¿Las interfaces? ¿Cómo?

Carmen: Tú declaras qué elementos quieres en la pantalla: un botón aquí, un texto allá. No le dices cómo dibujarlos píxel por píxel. Pero la lógica que se ejecuta al pulsar el botón... esa sí puede ser imperativa.

Mateo: ¡Qué bueno! Así que los lenguajes modernos mezclan ambos enfoques. Eso tiene mucho sentido.

Carmen: Totalmente. Entender ambos te da una capacidad increíble para resolver problemas desde distintos ángulos.

Mateo: Bien, ya tenemos al que da órdenes y al que pide deseos. Pero he oído hablar de otro que lo cambió todo... ¿el orientado a objetos?

Carmen: ¡Ahí querías llegar! Sí, el paradigma de Programación Orientada a Objetos, o POO. A veces lo verás como OOP, por sus siglas en inglés.

Mateo: POO... suena un poco... orgánico.

Carmen: ¡No seas así! Este paradigma fue una auténtica revolución en los años 60 y 70. Cambió radicalmente cómo pensamos el software.

Mateo: ¿Tan antiguo es? Yo pensaba que era más moderno.

Carmen: Pues no, sus raíces están en un lenguaje llamado Simula, allá por los 60. Pero quien realmente lo popularizó fue Alan Kay y su equipo en Xerox PARC con el lenguaje Smalltalk. ¡Una historia fascinante!

Mateo: Vale, me tienes enganchado. Esto de modelar el mundo con "objetos" suena a ciencia ficción. ¿Cómo funciona exactamente?

Carmen: Pues esa es la clave. Y para entenderla bien, vamos a dedicarle el próximo bloque entero, porque los conceptos de clase, herencia y polimorfismo merecen su propio espacio.

Mateo: Vale, y eso nos lleva a un ejemplo perfecto para ver cómo un mismo problema puede tener soluciones muy distintas. Hablemos de calcular el factorial de un número.

Carmen: ¡Exacto! Un clásico. Imaginen que tenemos dos funciones. El 'Enfoque A' usa un bucle, va multiplicando 1 por 2, por 3, y así sucesivamente hasta llegar al número.

Mateo: Súper directo. Lo entiendo perfectamente. Es como seguir una receta paso a paso, de forma lineal.

Carmen: Totalmente. Pero ahora viene lo interesante... el 'Enfoque B'. Esta función... se llama a sí misma para resolver el problema.

Mateo: ¿Cómo que se llama a sí misma? Suena a que podría entrar en un bucle infinito y explotar la computadora.

Carmen: ¡Casi! Pero no, porque es más inteligente. A este concepto lo llamamos recursión. Es una idea muy poderosa en programación.

Mateo: De acuerdo, entonces, ¿cómo funciona esa recursión sin causar un desastre?

Carmen: Piensa en ello de esta manera... La función dice: "Para calcular el factorial de 5, necesito saber el factorial de 4".

Mateo: Ah, ok. Y supongo que la función para el factorial de 4 dice que necesita el de 3, y así sucesivamente, ¿no?

Carmen: ¡Eso es! Como un eco que se va haciendo más pequeño. Cada llamada depende de la anterior hasta que llega a un punto final, un caso base. En el código, es la línea si n <= 1.

Mateo: Claro, esa es la condición que detiene el eco. Sin eso, sí tendríamos un problema.

Carmen: Exacto. Ese es el ancla. Así que ambos enfoques, el bucle y la recursión, llegan al mismo resultado, pero por caminos filosóficamente muy diferentes.

Mateo: Fascinante. Uno es un trabajador metódico y el otro es un... pensador que delega. Ahora, ¿cuál es más eficiente? Hablemos de eso.

Mateo: ...y esa es la clave de una buena estructura de datos. Pero, Carmen, tener los datos bien organizados no sirve de mucho si tardamos una eternidad en procesarlos, ¿verdad?

Carmen: ¡Exacto, Mateo! Ahí es donde entra el análisis de algoritmos. Es la forma en que medimos qué tan eficiente es una solución, sin importar si la corres en una supercomputadora o en tu celular.

Mateo: Suena como una especie de calificación. ¿Hay una nota para los algoritmos?

Carmen: ¡Casi! Usamos algo llamado notación Big O. Piénsalo como una etiqueta que te dice cómo crece el tiempo de ejecución de un algoritmo a medida que le das más y más datos.

Mateo: A ver si entiendo. Un algoritmo con una etiqueta O(n) es lineal, ¿no? Si le doy el doble de datos, tarda el doble de tiempo.

Carmen: ¡Precisamente! Pero uno O(n²), o cuadrático, se dispara. Con el doble de datos, podría tardar cuatro veces más. Para datos grandes, la diferencia es... abismal.

Mateo: Entonces siempre buscamos el algoritmo más rápido, el que tenga la mejor "nota" Big O en tiempo.

Carmen: Casi siempre. Pero hay otra cara de la moneda: la complejidad espacial. Es decir, ¿cuánta memoria extra necesita tu algoritmo para funcionar?

Mateo: Ah, el famoso *trade-off* o compromiso. A veces, para ser más rápido, necesitas usar más memoria, y viceversa.

Carmen: Exacto. Es un equilibrio. En un sistema con poca memoria, como un reloj inteligente, la complejidad espacial puede ser igual o más importante que la temporal.

Mateo: Y, ¿cómo podemos mejorar esto? ¿Hay trucos?

Carmen: Más que trucos, son estrategias inteligentes. Por ejemplo, los algoritmos voraces o *greedy*. Toman la mejor decisión posible en cada paso, esperando llegar a la mejor solución global.

Mateo: ¿Como cuando Google Maps busca la ruta más corta?

Carmen: ¡Ese es el ejemplo perfecto! El algoritmo de Dijkstra, que usa Maps, es un algoritmo voraz. No siempre garantizan la solución óptima para *todos* los problemas, pero cuando funcionan, son increíblemente eficientes.

Mateo: Muy bien, creo que lo tengo. ¿Qué te parece si ponemos a prueba lo que hemos aprendido con una microactividad rápida?

Carmen: ¡Me encanta la idea! ¡Dispara!

Mateo: Perfecto. Primera pregunta: tienes una lista pequeña de diez números y quieres ordenarla rápido. No te importa la eficiencia a gran escala. ¿Cuál usas? ¿Merge Sort, Burbuja o Quick Sort?

Carmen: Fácil. Para una lista tan pequeña, Burbuja es súper simple de implementar y la ineficiencia no se notará. ¡La respuesta es Burbuja!

Mateo: ¡Correcto! Siguiente: necesitas buscar un valor en una lista *que ya está ordenada*. ¿Qué algoritmo te da el mejor rendimiento?

Carmen: Ah, si está ordenada, la respuesta es siempre Búsqueda Binaria. Es increíblemente rápida porque divide el problema a la mitad en cada paso.

Mateo: ¡Exacto! Última: ¿Cuál es una situación ideal para usar recursividad?

Carmen: Uf, el ejemplo clásico es calcular el factorial de un número. Es un problema que se define en términos de sí mismo, ¡perfecto para la recursividad!

Mateo: ¡Tres de tres! Eres una experta. Conocer estos conceptos realmente marca la diferencia en el mundo real.

Mateo: Y con eso cerramos el tema anterior. ¡Qué intenso! Para nuestro último tema, Carmen, vamos a algo que suena súper importante: la Programación Orientada a Objetos.

Carmen: ¡Absolutamente! Y no es tan intimidante como suena. Piénsalo así: a nuestro alrededor vemos objetos. Perros, autos... todos tienen atributos, como el color, y comportamientos, como ladrar o acelerar. La POO imita eso.

Mateo: O sea, ¿mi código puede tener un perro que ladra?

Carmen: ¡Exactamente! O un objeto "Estudiante" que puede "inscribirse a un curso".

Mateo: Ok, me gusta la idea. ¿Y cómo funciona? ¿Cuáles son sus bases?

Carmen: Se apoya en cuatro pilares clave. El primero es el encapsulamiento. Esto significa que los datos y los métodos que los usan están juntos, protegidos dentro del objeto. Como una caja fuerte.

Mateo: Entiendo, así no se puede modificar algo por accidente.

Carmen: Justo. Luego está la herencia. Permite que una clase nueva, como "Estudiante", herede todo de una clase base, como "Persona", y luego añada sus propias cosas. Reutilizas código a tope.

Mateo: Suena muy organizado. ¿Qué más?

Carmen: Aquí viene lo genial: el polimorfismo. Significa "muchas formas". Permite que objetos de distintas clases respondan al mismo mensaje de su propia manera.

Mateo: A ver, un ejemplo, por favor. Que eso suena a hechizo.

Carmen: ¡Claro! Imagina una clase base "Figura" con un método "calcularÁrea". Un "Círculo" y un "Rectángulo" heredan de "Figura". Ambos saben cómo calcular su área, pero lo hacen de forma diferente. El polimorfismo permite que llames a "calcularÁrea" sin saber si es un círculo o un rectángulo.

Mateo: ¡Wow! Eso es súper flexible. Y el último pilar es... ¿abstracción?

Carmen: Sí. La abstracción es enfocarse en lo esencial e ignorar los detalles. Define qué debe hacer un objeto, pero no el cómo. Es el plano general antes de construir los detalles.

Mateo: Entonces, para recapitular: encapsulamiento, herencia, polimorfismo y abstracción. Suena como un cambio total en la forma de programar.

Carmen: Lo fue. Permitió crear sistemas más modulares, fáciles de mantener y que modelan el mundo real de forma más natural. Aunque, claro, un mal diseño puede complicarlo todo.

Mateo: El poder conlleva una gran responsabilidad.

Carmen: Como siempre en programación. Y con esa idea, hemos llegado al final de nuestro episodio de hoy.

Mateo: Así es. Esperamos que estos conceptos les hayan sido de gran ayuda. Gracias por acompañarnos en Studyfi Podcast. ¡Hasta la próxima!