Calcular el número feliz con Java

05/May/2012 Java , , , , , 1 Comentario

Ayer hablábamos en el grupo de Facebook sobre Java en Español (¿¿Qué todavía no estás apuntado???) sobre el cálculo de el número feliz con Java. Pero, ¿qué es un número feliz? Si seguimos la descripción de la wikipedia sobre el número feliz, este es aquel que, de forma iterativa, en la suma de sus dígitos acaba resultando un 1.

Es decir, para el caso del número 7, que es un número feliz, la secuencia sería la siguiente:

72 = 49
42 + 92 = 97
92 + 72 = 130
12 + 32 + 02 = 10
12 + 02 = 1

Así que nos ponemos manos a la obra para resolver este planteamiento de el número feliz con Java.

Lo primero que vemos es que hay que extraer los dígitos del número. Esto ya lo explicábamos en el artículo Dígitos de un número con Java. Así que es bueno que lo leas en detalle. Si bien, lo que hacemos es utilizar divisiones y el módulo del 10 (división y resto) para ir extrayendo los números del dígito.

  1. public static int[] digitosNumero(int iNumero){
  2.  
  3. // Creamos un array del tamaño del número de dígitos del número
  4. String x = Integer.toString(iNumero);
  5. int[] iNumeros = new int[x.length()];
  6.  
  7. // Método que devuelve los dígitos de un número
  8. int iDigito = 0;
  9. while (iNumero>0){
  10. iNumeros[iDigito] = iNumero%10;
  11. iNumero = iNumero/10;
  12. iDigito++;
  13. }
  14.  
  15. return iNumeros;
  16.  
  17. }

Al final hemos construido un método que dado un entero nos devuelve un array con los dígitos de dicho número.

Lo siguiente será, por cada dígito del número hacer la suma de los cuadrados de los dígitos. Para calcular los cuadrados utilizamos el método .pow() de la clase Math.

Recuerda que la clase Math es estática y no hace falta instanciarla.

El código de esta suma de dígitos al cuadrado sería:

  1. int[] iNumeros = digitosNumero(iNumero);
  2. iSuma = 0;
  3. for (int x=0;x<iNumeros.length;x++)
  4. iSuma += Math.pow(iNumeros[x],2);

Ahora hay que validar si la suma es un uno o si no saldremos del bucle. En el caso de que no sea un uno volvemos a llamar a la función digitosNumero para que nos vuelva a "trocear" el nuevo número.

  1. while (iSuma!=1){
  2. iSuma = 0;
  3.  
  4. for (int x=0;x<iNumeros.length;x++)
  5. iSuma += Math.pow(iNumeros[x],2);
  6.  
  7. iNumeros = digitosNumero(iSuma);
  8. }

Con esto ya tendríamos nuestro código que calcule si un número es un número feliz con Java terminado. Pero hay una cosa que se puede mejorar, y es que si el número no es feliz se mete en una secuencia infinita de calculos, ya que nunca encontrará el 1. Si bien, podemos cortar este bucle si se repite un número en la secuencia, ya que volverá a la misma secuencia.

Veamos el caso del número 2:

22 = 4
42 = 16
12 + 62 = 37
32 + 72 = 58
52 + 82 = 89
82 + 92 = 145
12 + 42 + 52 = 42
42 + 22 = 20
22 + 02 = 4

Al llegar al número 4 que ya estaba en la serie, todo se volverá a repetir de forma infinita. Es por ello que en este punto habría que cortar el cálculo.

Para implementar esto lo que hemos hecho es añadir un conjunto, es decir, un Set al programa, al cual vamos metiendo los números, siempre y cuando el número sumado no esté. Ya que si esta significará que la secuencia se vuelve a repetir y hay que salir del bucle.

Instanciamos el Set mediante una clase HashSet.

  1. Set<Integer> iCalculados = new HashSet<Integer>();

Y en mitad del bucle hacemos la comprobación o inserción en el conjunto. Para ello utilizamos los métodos .contains y .add

  1. if (iCalculados.contains(new Integer(iSuma)))
  2. bRepetido = true;
  3. else
  4. iCalculados.add(new Integer(iSuma));

Vemos que aparece una variable bRepetido y es que esta será el flag que utilicemos para salirnos del bucle. Así que finalmente nuestro bucle de cálculo quedará de la siguiente forma:

  1. while ((iSuma!=1) && !(bRepetido)){
  2. iSuma = 0;
  3. for (int x=0;x<iNumeros.length;x++)
  4. iSuma += Math.pow(iNumeros[x],2);
  5. iNumeros = digitosNumero(iSuma);
  6.  
  7. // Controlamos si ha salido un número repetido. Para no entrar en el bucle.
  8. if (iCalculados.contains(new Integer(iSuma)))
  9. bRepetido = true;
  10. else
  11. iCalculados.add(new Integer(iSuma));
  12. }

Ya solo nos quedará imprimir si el número es un número feliz o no. Esto nos lo cuenta la variable bRepetido. 😀

  1. if (bRepetido)
  2. System.out.println(iNumero + " NO es un número feliz");
  3. else
  4. System.out.println(iNumero + " SI es un número feliz");

Vídeos sobre Java


¿Algo que nos quieras comentar?

Déjanos tu comentario, no te preocupes que tu email no será publicado

*

*