DEV Community

Cover image for Ejercicios de logica y programacion (3 soluciones): Enfoques y Optimización
Juan Pino Contreras
Juan Pino Contreras

Posted on • Edited on

Ejercicios de logica y programacion (3 soluciones): Enfoques y Optimización

Dado este ejercicio: (desde codewars.com)

Crear una función que devuelva el cuadrado de cada dígito de un número.

Por ejemplo, al ingresar a la función el número 702 deberá devolver 4904, ya que el cuadrado de 7 es 49, el cuadrado de 0 es 0 y el cuadrado de 2 es 4. Si la función recibe un cero debe devolver 0.

Como todo en programación, es posible resolver este ejercicio de muchas formas. Primero, vamos a resolverlo usando las propiedades de manipulación de números en Python, luego explicaré otra forma más avanzada 🤓.

def square_digits(num):
    if num == 0:
        return 0
    result = ""
    while num > 0:
        num_sqr = (num % 10) ** 2 
        num = num // 10
        result = str(num_sqr) + result 
    return int(result)
Enter fullscreen mode Exit fullscreen mode

En este código, primero evaluamos si se recibe un 0 para retornar un 0, tal como indica el enunciado. Luego, inicializamos la variable result como un string vacío, creamos un ciclo while con la condición num > 0. Definimos la variable num_sqr, que es el cuadrado de cada dígito recibido. Con num % 10 obtenemos el último dígito del número recibido para luego elevarlo al cuadrado con **2.

  • El uso de num % 10 es un método común para extraer el último dígito de un número.

  • La expresión num = num // 10 elimina el último dígito del número, avanzando en el recorrido de cada dígito.

Otra forma de resolverlo es convertir el número en un string y recorrer este string con un ciclo for:

def square_digits(num):
    result = ""
    for digit in str(num):
        result += str(int(digit)**2)
    return int(result)
Enter fullscreen mode Exit fullscreen mode

Este código es más óptimo, tiene menos líneas y se entiende muy bien el recorrido, además de que no es necesario evaluar si recibe un 0. En Python es posible recorrer carácter por carácter de un string con un ciclo for. Usamos esta funcionalidad para recorrer el número recibido, convirtiéndolo con str(num) a un string. Creamos la variable resultcomo un string vacío, al cual se le concatenará un carácter que es el resultado de digit convertido a entero y elevado a 2, todo esto convertido a un string. Luego, retornamos el resultado convertido a un entero.

  • Concatenar strings dentro de un bucle puede ser menos eficiente en términos de rendimiento para números muy largos, pero es perfectamente aceptable para la mayoría de los casos de uso.

*Una forma mas avanzada y "elegante" * es usando Comprension de generadores y el motodo .join. Te presento el codigo primero y vamos desglosando explicando estos terminos.

def square_digits(num):
    return int(''.join(str(int(digit)**2) for digit in str(num)))
Enter fullscreen mode Exit fullscreen mode

Este código de primeras no es muy legible si no se conocen los conceptos
que lo conforman.

La expresión str(int(digit)**2) for digit in str(num) es un _generador _(Generator Expression) que itera sobre cada dígito en la representación en cadena del número num.
Para cada dígito, lo convierte en un entero (int(digit)), lo eleva al cuadrado (**2), y luego lo convierte nuevamente en una cadena (str(...)). Luego, con ''.join(...), toma una secuencia (en este caso, el generador) y concatena todos los elementos en una única cadena. Aquí, todos los cuadrados de los dígitos se combinan en una sola cadena sin ningún separador (debido a que la cadena entre las comillas simples es vacía '').

Como vemos, las diferentes formas de resolver un ejercicio demuestran los niveles de conocimiento en un lenguaje. Todas las soluciones son correctas si pasan las pruebas, pero algunas son más eficientes y legibles que otras. La elección del enfoque depende del contexto y de lo que se priorice en cada caso:

  • Legibilidad: Es crucial cuando otros desarrolladores van a leer y mantener tu código. Un código claro y fácil de entender reduce la posibilidad de errores y facilita su mantenimiento. 📖

  • Eficiencia: Importa cuando se trabaja con grandes volúmenes de datos o en aplicaciones donde el rendimiento es crítico. Un código más optimizado puede hacer una gran diferencia en la velocidad y el consumo de recursos. 🚀

  • Simplicidad: Para casos donde la prioridad es resolver el problema de forma rápida y directa, como en prototipos o ejercicios didácticos. La simplicidad a menudo facilita la depuración y pruebas del código. 😉

Al desarrollar, es importante encontrar un balance entre estas consideraciones, adaptando la solución a las necesidades específicas del proyecto o tarea.

Top comments (0)