Kata #3 - Happy Number

A language that doesn't affect the way you think about programming is not worth knowing.

Happy Number es un Kata muy divertido que se define así: Escribir un algoritmo para determinar si un número es “feliz”. Los números felices se definen por el siguiente procedimiento: empezando con cualquier número entero positivo, se reemplaza el número por la suma de los cuadrados de sus dígitos, y se repite el proceso hasta que el número es igual a 1, si el número nunca llega a 1, se dice que es un número infeliz :(

La clave de éste kata está en saber cuando un número -_con los pasos definidos para encontrar un happy number_- nunca llegará a 1. Bien, eso significa que es un bucle, y un bucle significa que hay una repetición. En pocas palabras, habrá un punto en el que el procedimiento nos arroje un número repetido. Pero, ¿cómo seguimos el trayecto de esto? Sencillo, con algo llamado Memoization -_no se espanten, básicamente es una fancy word pero después de decirla se sentirán mas chidos consigo mismos_-.

Memoization es una técnica de optimización utilizado principalmente para acelerar los programas mediante el almacenamiento de los resultados de las llamadas a funciones y devolver el resultado almacenado en caché cuando se producen las mismas entradas de nuevo.

Utilizaremos memoization para guardar el resultado del procedimiento, esto nos dará la herramienta que necesitamos para comparar si ya entramos en un bucle infinito. Ya que estamos con esta técnica, vamos a aprovechar que nos queremos ver cools y resolveremos esto en un estilo a la functional programming.

  1. Crearemos un Array memo.
  2. Convertiremos nuestro número n en un string.
  3. Haremos un split por character.
  4. Usaremos map para recorrer el arreglo -_que nos hizo split_- y elevar al cuadrado cada elemento del arreglo.
  5. Finalizando con reduce, quien hará la magia de acumular el resultado del arreglo final de map.

Siguiendo esos pasos, sólo nos falaría encerrar los pasos 2..5 en un ciclo mientras n > 1 y n no exista en nuestro memo.

const isHappy = function(n) {
  const memo = [];
  
  while(n>1 && !memo.includes(n)){
    memo.push(n);
    n = n.toString()
         .split("")
         .map((x) => Math.pow(+x, 2))
         .reduce((memo, x) => memo + x, 0);
  }
    
  return n == 1;
};

JS Bin on jsbin.com

Aquí vemos el poder que nos otorga trabajar con funciones como map y reduce. Una cosa muy interesante -_del que luego hablaré_- es lo que podemos lograr el conocer las funciones que podemos utilizar en el objecto Array. Todo en la vida de un programa son las colecciones, así que no olviden darle una leída a las funciones que manejan colecciones en el lenguaje que mas usan.

Nos leemos!!!