EX: soma dos digitos de 100!

30 respostas
wizardkronuz

alguem poderia me dizer se o codigo abaixo da o resultado correto ?

import javax.swing.JOptionPane;


public class Ex4
 {
     public static void main(String args[])
          {
                  String strOriginal = JOptionPane.showInputDialog("Digite o número:");
                  String num = strOriginal;
                  int tamanho = num.length();
                  int soma = 0;
                if (tamanho==1) soma = Integer.parseInt(num);	    
                  while (tamanho >1)
                 {
                         soma = 0;
                         for (int i = 0; i< tamanho; i++)
                        {
                              soma+= Integer.parseInt(num.substring(i,i+1));
                        }
                        num = Integer.toString(soma);
                        tamanho = num.length();
                 }	  
                 String resultado = strOriginal+ "-" + soma;
                 JOptionPane.showMessageDialog(null,"O número com seu dígito "+
                           "verificador é: "+ resultado);
            }
 }

30 Respostas

joede.fadel

dando uma rápida olhada no seu código ele vai dar o resultado certo sim, mas você deu uma complicada em algumas partes do seu código que poderia se simplificado.

Lavieri

depende de qual é o resultado que vc espera ^^

rodrigo.bossini

Cara, se entendi direito, vc ta querendo fazer a soma de 1 até n. Assim: 1 + 2 + 3 + 4 + ....+ n. Correto?

Se for isso, vc nem precisa de laço.

Se n for par, a soma de 1 até n é igual a: (n(n+1))/2.

Se n for impar a soma de 1 até n é igual a: ((n(n-1))/2) + n.

Em java:
import javax.swing.JOptionPane;
class Teste{
	public static void main (String args[]){
		try{ //coloquei o try catch só pro caso de vc querer tratar o caso de o usuário digitar algo que não seja um número.
			int soma = 0;
			int n = Integer.parseInt(JOptionPane.showInputDialog (null, "digite numero"));
			if ( n % 2 == 0){	//checa pra ver se o número é par.
				 soma = (n*(n+1))/2;
			} 
			else{ 			//cai aqui se o número for ímpar
				
				 soma = ((n*(n-1))/2) + n;	
			}

			JOptionPane.showMessageDialog (null, "Resultado: " + soma,"Resultado",JOptionPane.INFORMATION_MESSAGE); 
		}
		catch (Exception e){
			
		}

	}
}
wizardkronuz

rod.Attack

o exercicios é
n! significa n * (n - 1)! = n * … * 3 * 2 * 1
Encontre a soma dos dígitos do número 100!

pesquisei um pouco e encontrei o resultado de 648
só não sei se o código está correto

rodrigo.bossini

wizardkronuz:

rod.Attack

o exercicios é
n! significa n * (n - 1)! = n * … * 3 * 2 * 1
Encontre a soma dos dígitos do número 100!

pesquisei um pouco e encontrei o resultado de 648
só não sei se o código está correto

Fatorial é a multiplicação de n números, começando em n e terminando em 1.

A soma dos digitos não é a mesma coisa que fatorial. Não entendi.

T

Estou vendo que um monte de gente quer a solução para este problema:

“Ache a soma dos dígitos da representação decimal do fatorial de 100”.

Obviamente, o fatorial de 100 é, em representação decimal, 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 , como se pode constatar fazendo um programa qualquer. Esse pessoal quer achar a soma desses dígitos, que é 648.

J

Não é que eu também tinha dúvida nesse exercício :smiley:

wizardkronuz

thingol:
Estou vendo que um monte de gente quer a solução para este problema:

"Ache a soma dos dígitos da representação decimal do fatorial de 100".

Obviamente, o fatorial de 100 é, em representação decimal, 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 , como se pode constatar fazendo um programa qualquer. Esse pessoal quer achar a soma desses dígitos, que é 648.

hummmmm
seria algo assim então ?
o problema que depois do fatorial de 65 ele vira 0

public class Ex5
 {
     public static void main(String args[])
          {

         long numero = 1;
         long resposta = 1;
         
        
        long cont;
        
         while(numero <= 100){
         for(cont = numero; cont > 1 ; cont--) {
             resposta = resposta * (cont);
         }
       System.out.println("Fatorial de "+numero+" é "+resposta);
          numero ++;
            resposta = 1;
        }
         System.out.println( resposta +" resultado" + (resposta * ( resposta -1)));
    }
          
  }
T

A idéia do tal exercício é que você não use long ou int, mas um outro tipo de dado (java.math.BigInteger), ou então você bole uma maneira de achar a soma dos dígitos do fatorial de outra forma que não calculando o fatorial.

rodrigo.bossini
thingol:
A idéia do tal exercício é que você não use long ou int, mas um outro tipo de dado (java.math.BigInteger), ou então você bole uma maneira de achar a soma dos dígitos do fatorial de outra forma que não calculando o fatorial.
Resolvido com BigInteger:
import javax.swing.JOptionPane;
import java.math.*;
class Teste{
	public static void main (String args[]){
		BigInteger n =new BigInteger(JOptionPane.showInputDialog (null, "digite:"));
		BigInteger res = fatorial (n);
		String s = new String (res.toString());
		int soma = 0;
		int index = 0;
		while (index < s.length()){
			soma += Integer.parseInt (Character.toString(s.charAt(index)));
			index += 1;
		}
			
			

		JOptionPane.showMessageDialog (null, "Resultado: " + soma, "Resultado:" , JOptionPane.INFORMATION_MESSAGE);

	}

	static BigInteger fatorial(BigInteger n){
	  if (n.equals(new BigInteger (Integer.toString (0))) || n.equals(new BigInteger (Integer.toString (1)))) return new BigInteger(Integer.toString(1));

	  return (n.multiply( fatorial (n.add (new BigInteger (Integer.toString(-1))))));
	}
}
wizardkronuz

uhuuuuuuuuuuuuuuuuuuuuu

VALEW rod.attack

Lavieri
Não sei fazer sem calcular o fatorial, se alguem conseguiu, por favor me ajude ^^
public static void main(String args[]) {
          int soma = 0;
          for (char c : fatorial(100).toString().toCharArray())
              soma += Integer.valueOf(String.valueOf(c));
          System.out.println(soma);
    }

    public static BigInteger fatorial(long n) {
        return fatorial(BigInteger.valueOf(n));
    }

    /**
     * N! = N * [(N-1)!]
     * 0! = 1
     * @param n
     * @return
     */
    public static BigInteger fatorial(BigInteger n) {
        if (n.compareTo(BigInteger.ZERO) == -1)
            throw new IllegalArgumentException("N value cannot be null");
        return fatorialInterno(n);
    }

    private static BigInteger fatorialInterno(BigInteger n) {
        BigInteger nMinus1 = n.subtract(BigInteger.ONE);
        return (n.equals(BigInteger.ZERO)) ? BigInteger.ONE : n.multiply(fatorial(nMinus1));
    }
}
David

Na verdade, (n(n+1))/2 é a mesma coisa que ((n(n-1))/2) + n.

(n(n+1))/2 = ((n(n-1))/2) + n
(n^2 + n) / 2 = (n^2 - n) / 2 + 2n / 2
(n^2 + n) / 2 = (n^2 - n + 2n) / 2
(n^2 + n) / 2 = (n^2 + n) / 2
0 = 0.

Não é necessário fazer esse teste, basta usar sempre a primeira fórmula.

rodrigo.bossini
Lavieri:
Não sei fazer sem calcular o fatorial, se alguem conseguiu, por favor me ajude ^^
public static void main(String args[]) {
          int soma = 0;
          for (char c : fatorial(100).toString().toCharArray())
              soma += Integer.valueOf(String.valueOf(c));
          System.out.println(soma);
    }

    public static BigInteger fatorial(long n) {
        return fatorial(BigInteger.valueOf(n));
    }

    /**
     * N! = N * [(N-1)!]
     * 1! = 1
     * @param n
     * @return
     */
    public static BigInteger fatorial(BigInteger n) {
        BigInteger nMinus1 = n.subtract(BigInteger.ONE);
        return (n.equals(BigInteger.ONE)) ? n : n.multiply(fatorial(nMinus1));
    }

calcule o fatorial de forma recursiva:

int fatorial (int n){
  if ( n == 0 || n ==1)  // retorna 1 direto se n for igual a 0 ou 1
     return 1;

  return (n * (fatorial (n-1)); // retorna n *(n-1)!


}
rodrigo.bossini

David:
rod.attack:

Se n for par, a soma de 1 até n é igual a: (n(n+1))/2.

Se n for impar a soma de 1 até n é igual a: ((n(n-1))/2) + n.

Na verdade, (n(n+1))/2 é a mesma coisa que ((n(n-1))/2) + n.

(n(n+1))/2 = ((n(n-1))/2) + n
(n^2 + n) / 2 = (n^2 - n) / 2 + 2n / 2
(n^2 + n) / 2 = (n^2 - n + 2n) / 2
(n^2 + n) / 2 = (n^2 + n) / 2
0 = 0.

Não é necessário fazer esse teste, basta usar sempre a primeira fórmula.

Verdade cara, logo depois que postei a mensagem também fiz esse teste.

Interessante isso, se vc parar pra imaginar, dá impressão que se n for ímpar, o n sempre vai sobrar, não vai ser incluído na soma, usando a primeira fórmula.

Lavieri
rod.attack:
Lavieri:
Não sei fazer sem calcular o fatorial, se alguem conseguiu, por favor me ajude ^^
public static void main(String args[]) {
          int soma = 0;
          for (char c : fatorial(100).toString().toCharArray())
              soma += Integer.valueOf(String.valueOf(c));
          System.out.println(soma);
    }

    public static BigInteger fatorial(long n) {
        return fatorial(BigInteger.valueOf(n));
    }

    /**
     * N! = N * [(N-1)!]
     * 1! = 1
     * @param n
     * @return
     */
    public static BigInteger fatorial(BigInteger n) {
        BigInteger nMinus1 = n.subtract(BigInteger.ONE);
        return (n.equals(BigInteger.ONE)) ? n : n.multiply(fatorial(nMinus1));
    }

calcule o fatorial de forma recursiva:

int fatorial (int n){
  if ( n == 0 || n ==1)  // retorna 1 direto se n for igual a 0 ou 1
     return 1;

  return (n * (fatorial (n-1)); // retorna n *(n-1)!


}

esta recursivo... fui ate olhar no google, que tinha esquicido que 0! = 0 .... ^^
prefiro no lugar de estar n ==0 e n ==1 ... melhor testar apenas n ==0 ... sei que isso vai fazer passar mais 1 vez dentro da recursividade, porem eu vou evitar N testes a menos pois não terei mais o ||

por isso troquei a ultima linha q era....
"return (n.equals(BigInteger.ONE)) ? n : n.multiply(fatorial(nMinus1));"
por
"return (n.equals(BigInteger.ZERO)) ? n : n.multiply(fatorial(nMinus1));"

rodrigo.bossini
Lavieri:
rod.attack:
Lavieri:
Não sei fazer sem calcular o fatorial, se alguem conseguiu, por favor me ajude ^^
public static void main(String args[]) {
          int soma = 0;
          for (char c : fatorial(100).toString().toCharArray())
              soma += Integer.valueOf(String.valueOf(c));
          System.out.println(soma);
    }

    public static BigInteger fatorial(long n) {
        return fatorial(BigInteger.valueOf(n));
    }

    /**
     * N! = N * [(N-1)!]
     * 1! = 1
     * @param n
     * @return
     */
    public static BigInteger fatorial(BigInteger n) {
        BigInteger nMinus1 = n.subtract(BigInteger.ONE);
        return (n.equals(BigInteger.ONE)) ? n : n.multiply(fatorial(nMinus1));
    }

calcule o fatorial de forma recursiva:

int fatorial (int n){
  if ( n == 0 || n ==1)  // retorna 1 direto se n for igual a 0 ou 1
     return 1;

  return (n * (fatorial (n-1)); // retorna n *(n-1)!


}

esta recursivo... fui ate olhar no google, que tinha esquicido que 0! = 0 .... ^^
prefiro no lugar de estar n ==0 e n ==1 ... melhor testar apenas n ==0 ... sei que isso vai fazer passar mais 1 vez dentro da recursividade, porem eu vou evitar N testes a menos pois não terei mais o ||

Relaxa cara, eu que li sua pergunta errada. Você escreveu "não sei sem fazer o fatorial". Eu li "não sei calcular o fatorial"...hahahahaha
Mas 0! = 0 tá errado. 0! = 1 .

Veja:

n! = n * (n-1)!

com n = 1 temos:

1! = 1 * (0!) o que implica em 0! =1 :)

Lavieri
rod.attack:

Relaxa cara, eu que li sua pergunta errada. Você escreveu "não sei sem fazer o fatorial". Eu li "não sei calcular o fatorial"...hahahahaha
Mas 0! = 0 tá errado. 0! = 1 por definição.

sim sim... eu escrevi ali no post... 0! = 0 .... mais na solução ta la... 0! = 1 =x.... e no javaDoc tb

/** 
* N! = N * [(N-1)!] 
* 0! = 1 
* @param n 
* @return 
*/
T

Vou fazer uma pergunta.

Quantos zeros tem o fatorial de 1000, representado em notação decimal?

Atenção: a sua resposta não pode usar BigInteger.

rodrigo.bossini

thingol:
Vou fazer uma pergunta.

Quantos zeros tem o fatorial de 1000, representado em notação decimal?

Atenção: a sua resposta não pode usar BigInteger.

Quantidades de zeros = multiplicação de cada fator 5 e 2 do número 1000!.

Lavieri

thingol:
Vou fazer uma pergunta.

Quantos zeros tem o fatorial de 1000, representado em notação decimal?

Atenção: a sua resposta não pode usar BigInteger.

Pode BigDecimal ??? =x uhuhhuhu

victorwss

A soma dos digitos é fácil:private static BigInteger somaDigitos(BigInteger valor) { BigInteger soma = BigInteger.ZERO; while (valor.compareTo(BigInteger.ZERO) > 0) { BigInteger valores[] = valor.divideAndRemainder(BigInteger.TEN); soma = soma.add(valores[1]); valor = valores[0]; } return soma; }Ou então:private static int somaDigitos(BigInteger valor) { int soma = 0; while (valor.compareTo(BigInteger.ZERO) > 0) { BigInteger valores[] = valor.divideAndRemainder(BigInteger.TEN); soma += valores[1].intValue(); valor = valores[0]; } return soma; }

EDIT: Erro apontado pelo ozix corrigido.

B

thingol:
Vou fazer uma pergunta.

Quantos zeros tem o fatorial de 1000, representado em notação decimal?

Atenção: a sua resposta não pode usar BigInteger.

public static int quantidadeDeZerosADireitaNoFatorialDeNRepresentadoEmNotacaoDecimal (int n) { return n / 5; } :wink:

T

Bruno Laturner:
thingol:
Vou fazer uma pergunta.

Quantos zeros tem o fatorial de 1000, representado em notação decimal?

Atenção: a sua resposta não pode usar BigInteger.

public static int quantidadeDeZerosADireitaNoFatorialDeNRepresentadoEmNotacaoDecimal (int n) { return n / 5; } :wink:

25! = 15511210043330985984000000 que tem 6 zeros, contraexemplo para sua fórmula.

victorwss
thingol:
Bruno Laturner:
thingol:
Vou fazer uma pergunta.

Quantos zeros tem o fatorial de 1000, representado em notação decimal?

Atenção: a sua resposta não pode usar BigInteger.
public static int quantidadeDeZerosADireitaNoFatorialDeNRepresentadoEmNotacaoDecimal (int n) {
  return n / 5;
}
:wink:

25! = 15511210043330985984000000 que tem 6 zeros, contraexemplo para sua fórmula.

Falha porque múltiplos de 25=5², ou seja, conta duas vezes. 125=5³, conta 3 vezes.

Assim funciona?
public static int quantidadeDeZerosADireitaNoFatorialDeNRepresentadoEmNotacaoDecimal (int n) {
    int resposta = 0;
    while (n > 0) {
       resposta += n / 5;
       n /= 5;
    }
    return resposta;
}
T

A do Victor parece estar certa. Como sabemos, o número dos zeros à direita de N! é o número de vezes que 10 consegue dividir N; ou seja, é o número de vezes que 5 consegue dividir N.

Traduzindo o programa do Victor, o número de vezes que 5 consegue dividir N! é o número dos números divisíveis por 5 que vão de 1 até N, mais o número dos números divisíveis por 25 (5^2) que vão de 1 até N, mais o número dos números divisíveis por 125 (5^3) que vão de 1 até N, e assim por diante.

Parabéns!

T

Para mais problemas desse tipo, dirijam-se a projecteuler.net. Foi daí que o professor do Java_Machine deve ter tirado o problema. (Eu gostaria de saber qual é o ranking do professor :slight_smile: )

http://projecteuler.net/index.php?section=scores&country=Brazil

B

Sabia q devia ter testado com mais de 20! :stuck_out_tongue:

Deixa eu adivinhar… a cada multiplo de expoentes de 5, o numero aumenta em 2… Eu imagino que quando ele ir de 124! para 125!, ele deve aumentar em 3.

Só chutando aqui, mas acho que a formula correta deve ser (n / 5) + (n / 25) + (n / 125) + (n / 625) + …

Edit: Ninja’ed pelo Victor. :shock:

O
victorwss:
A soma dos digitos é fácil...
Parabéns. Vou colocar em variáveis primitivas pra ficar melhor de ententer. O seu algoritmo fica assim:
public static int somaDosDigitos(long n) {
      int soma = 0;
      while (n > 0) {
         soma += n % 10;
         n /= 10;
      }
      return soma;
   }
Eu to morrendo de vergonha aqui. Passei um tempão pra chegar nessa alquimia, rsrs:
public static int somaDosDigitos(long n) {
      long d = 1;
      int soma = 0;
      while (d < n) {
         d *= 10;
         soma += (n % d * 10) / d;
      }
      return soma;
   }
Ou seja, viajei. Só uma coisa, acho que você não testou seu código. Troque a linha 3 por
while (valor.compareTo(BigInteger.ZERO) == 1) {
Mas pelo visto a melhor idéia veio do thingol mesmo. Veja o teste abaixo para os dois métodos. Usei o fatorial de 10000 pra ter valor significativo:
import java.math.BigInteger;

public class FactorialDigitSum {
   
   public static BigInteger fatorial(int n) {
      BigInteger fat = BigInteger.ONE;
      for (int i = 1; i <= n; i++) {
         fat = fat.multiply(BigInteger.valueOf(i));
      }
      return fat;
   }
   
   public static int somaDosDigitosComString(BigInteger n) {
      int soma = 0;
      char[] digitos = n.toString().toCharArray();
      for (int c : digitos) {
         soma += c - 48;// 48 é o 0 (zero) na tabela ASCII
      }
      // A subtração também pode ser feita como abaixo. Testei mas não houve queda no tempo.
      // soma -= 48 * digitos.length;
      return soma;
   }
   
   public static int somaDigitos(BigInteger valor) {
      int soma = 0;
      while (valor.compareTo(BigInteger.ZERO) == 1) {
         BigInteger valores[] = valor.divideAndRemainder(BigInteger.TEN);
         soma += valores[1].intValue();
         valor = valores[0];
      }
      return soma;
   }
   
   public static void main(String[] args) {
      BigInteger fat = fatorial(10000);
      
      long ini = System.currentTimeMillis();
      System.out.println(somaDigitos(fat));
      long fim1 = System.currentTimeMillis();
      System.out.println(somaDosDigitosComString(fat));
      long fim2 = System.currentTimeMillis();
      
      System.out.println("Tempo somaDigitos: " + (fim1 - ini));
      System.out.println("Tempo somaDosDigitosComString: " + (fim2 - fim1));
   }
}
victorwss

Não, não testei mesmo, escrevi direto aqui no GUJ. Valeu por apontar a falha, vou editar aquilo para arrumar (assim se alguém chegar aqui através google, pega aquilo certo).

Criado 4 de março de 2009
Ultima resposta 6 de mar. de 2009
Respostas 30
Participantes 10