Finalmente
En los tiempos muertos que tengo, ps decidí seguir con los problemas del
7
// suma = 41l;
8 suma=5l;
9 while (primos.get(primos.size()-1) <= 2e6){
Boolean esPrimo=false;
11
Boolean salidaOk;
12
while(!esPrimo){
13
salidaOk= true;
14
// System.out.println("Numero a evaluar: "+numero+" {");
15
raizNumero = Math.floor(Math.sqrt(numero));
16
// System.out.print("\tPrimer Corte Control: "+raizNumero+
17
for(Long val: primos){
19 if (val>raizNumero) {
21 break;
}else{
22
if (numero % val == 0) {
23
//ya no es un primo, se aumenta el numero en 2
24
// System.out.print("\n\tNo es primo. Sale del For:
25
salidaOk=false;
26
break;
27
}
28
}
29
}
30 if (!salidaOk) {
numero+=2;
32
}else{
33
// System.out.print("\n\tNúmero primo encontrado: "+num
34
esPrimo=true;
35
}
36
}
37
primos.add(numero);
38
if (numero<2e6) {
39 suma+=numero;
40 }
41 }
}
43
}
44
45
46
47
48
long num = 600851475143L, may = 0; //la variable mayor guardara el mayor múltiplo
//el ciclo va hasta la raíz del numero, según una formula matemática los factores primos no
exceden //la raíz del numero
if(num % x == 0){
} //fin si
} //fin si
} //fin para
//al final el numero que este en la variable may sera el mayor múltiplo
} //fin principal
/*Lo que hace la función es empezar en el primer primo conocido: el 2, e ir hasta la raíz del
numero, si en el
camino se encuentra con que la operación de modulo es igual a cero, pues significa que el
numero NO es primo y se interrumpe la ejecución*/
if(i % y == 0){
return false;
}//fin si
}//fin para
return true;
}//fin ConsultaPrimo
********************************************************************************************************
Ahora pasemos a una solucion mas practica y elegante que nos evita la necesidad de utilizar
una función...
Num sera el número. F sera el factor, por cada F si es factor de Num entonces
dividimos Num por F (Num/F) antes de pasar a la siguiente F.
Se puede observar (mas fácilmente mediante una prueba de escritorio) que cuando F es factor
de Num, necesariamente sera Primo, como todos los factores mas pequeños ya han sido
removidos entonces al final el resultado sera Num = 1.
El único numero primo que es par es el 2, por lo que la variable factor empieza en 1 y se
incrementa de 2 en 2, por lo que solo tomara números impares, esto ahorra la mitad de las
comparaciones, disminuyendo el tiempo de ejecución.
//se comprueba si el numero es par, recordemos que el único numero par que es primo es el
2
if(num % 2 == 0){
num = num / 2;
ult_fac = 2;
while(num % 2 == 0){
num = num / 2;
} //fin mientras
} //fin si
factor = 3;
ult_fac = 1;
ult_fac = factor;
} //fin mientras
} //fin si
factor+= 2; //se incrementa en 2 porque se obvian los pares, se cuentan los impares
} //fin mientras
} //fin si
Resultado: 6857
Tiempo de ejecución: 1 ms
Como lo he mencionado en los ejercicios anteriores, si cambiamos la cifra inicial por un numero
mucho mas grande, notaremos la diferencia en tiempo de ejecución que ofrece el segundo
ejercicio.
Para los que tienen cuenta en ProjectEuler, podrán ver que una vez ingresen la
respuesta les aparecerá un documento en formato PDF en donde verán este ultimo ejercicio
con una mejora mas, es decir, le realizan una optimización que mejora aun mas el tiempo
de ejecución. Les recomiendo que lean cada uno de los documentos que entrega el
proyecto después de ingresada la solución pues amplia tus conocimientos y son un muy
buen ejercicio mental.
Saludos
Vamos a dar solución a este ejercicio como lo hicimos con el primer ejercicio, es decir, uno
por fuerza bruta y otro mas depurado.
Lo que se me ocurrió en el primer ejercicio es generar la secuencia Fibonacci y una vez generado
cada termino, evaluarlo para determinar si es par (con MOD de 2), en caso afirmativo, pues
sencillamente se acumula o se van sumando, asi:
/* los primeros dos terminos de la serie son: 1 (ant --> anterior) y 2 (act --
> actual). La variable tg almacenara el Termino Generado que es el resultado
de la suma de ant + act*/
tg = ant + act;
ant = act;
act = tg;
} //fin mientras
*********************************************************************************
El tiempo de ejecución es corto, pero vale la pena resaltar que si se reemplaza el limite de
4000000 por una cifra mas alta, este algoritmo dejara de ser eficiente. La segunda solución se
basa en que cada 3 términos de la serie Fibonacci se genera un número par: 1, 1, 2, 3, 5, 8, 13,
21, 34, 55, 89, 144,... Veamos la solucion:
suma += tg;
tg = ant + act;
} //fin mientras
Respuesta: 4613732
Saludos
Etiquetas: Ejercicio 2
Existen muchas maneras de abarcar el ejercicio, realizare 2, una por fuerza bruta y otra mas
depurada. Tal vez la mas común sea recorrer los números desde 3 hasta N (N en este caso es
1000) y realizar una operación de Modulo (donde tomamos el residuo y no el cociente) sobre
cada número por 3 y 5 para determinar si el numero es múltiplo de los números mencionados.
En palabras mas sencillas se divide cada numero (del 3 a N) por 3 y por 5, si su residuo es cero,
significa que es múltiplo y se van acumulando...
//Le resto a la variable fin la variable inicio para saber el tiempo total en
milisegundos*/
System.out.println("Tiempo de ejecucion: " + (fin - inicio) + " ms");
}
Este algoritmo entrega la respuesta inmediatamente ¿pero que pasaría si no fuera hasta
1000 sino hasta 1.000.000 o hasta 10.000.000 o más? La respuesta es simple:
se tardaría mucho más tiempo o en ocasiones provocaría que el computador colapse, por este
motivo la segunda solución es mucho mas elegante y sirve para números mucho mas grandes.
Antes de leer el código es necesario tener en cuenta lo siguiente: lo que hace el algoritmo es
sumar los múltiplos de 3 y los múltiplos de 5 MENOS los múltiplos de 15
¿porque? porque cuando se suman los múltiplos de 3, el 15 y sus múltiplos van incluidos
o sumados y cuando suma los múltiplos de 5 OTRA VEZ se suma el 15 y
sus múltiplos, así que al final hay que restarlo (recordemos que 15 es múltiplo de 3 y de 5).
}//fin principal
/*La funcion --> SumaDivisiblePor() suma los números que sean divisibles por
la variable que se envie como parametro (x)*/
Explicación:
sabemos que para sumar los números de 1 hasta una variable N, utilizamos la siguiente
formula: n * (n + 1) / 2. Ahora:
sumar los múltiplos del 3 al 999 es igual que sumar los números del 3 al 333 y multiplicarlo por
3, así:
3 + 6 + 9 + 12 + ... + 999 = (1 + 2 + 3 + ... + 333) * 3 --> esta es la formula que se utiliza, que
es lo mismo que decir (n * (n + 1) / 2) * 3
el 333 resulta de dividir el limite (en este caso 999, recordemos que son los números DEBAJO
de 1000) por 3 o por 5, según sea el caso.
Resultado: 233168
Saludos
Etiquetas: Ejercicio 1
n ! significa n × ( n - 1) × ... × 3 × 2 × 1
Código Java:
Ver original
A ver el problema esta en la variable DIVISOR, cuando pongo un numero chiquitito(como 20)hace
bien los (*10) pero cuando es un numero muy grande como por ejemplo 100, entonces el Divisor
cuando llega a una cantidad muuuuuy grande, "se vuelve loco" y lo que hace es que se vuelve
negativo.
Nota: No me hagan el código porfavor, prefiero que me ayudes antes que me hagas el código, para
mejorar, gracias.
Que rabia me da
Código Java:
Ver original
Creo que asi ahora esta mejor, por que muchas veces la diferencia era de 2-3 ceros
Aunque sigue fallando en numeros altos como el 100
n ! significa n × ( n - 1) × ... × 3 × 2 × 1
Código: Java
1. import java.math.BigInteger;
2. public class prueba
3. {
4. public static void main(You are not allowed to view
links. Register or Login[] args) {
5. int valor = 1;
6. You are not allowed to view links.
Register or Login b1 = new You are not allowed to view links.
Register or Login("1");
7. int NumeroFin = 0;
8. int FinalNumero = 0;
9. You are not allowed to view links. Register or Login
NumeroFinCadena = "";
10. long fin = 100;
11. You are not allowed to view links.
Register or Login Sumatorio = new You are not allowed to view
links. Register or Login("1");
12. You are not allowed to view links.
Register or Login Contador = new You are not allowed to view
links. Register or Login("1");
13. for(int i = 1; i <= fin;i++){
14. b1 = b1.multiply(Sumatorio);
15. Sumatorio = Sumatorio.add(Contador);
16. if(i == fin){
17. You are not allowed to view links.
Register or Login.out.println(b1);
18. NumeroFinCadena = You are not allowed to view
links. Register or Login.valueOf(b1);
19. FinalNumero =NumeroFinCadena.length();
20.
21. }
22.
23. }
24. You are not allowed to view links.
Register or Login b2 = new You are not allowed to view links.
Register or Login("1");
25. You are not allowed to view links.
Register or Login Multiplicador = new You are not allowed to
view links. Register or Login("10");
26. int Compara = 0;
27. Compara = b1.compareTo(b2);
28. for(int i = 0 ; i <= fin;i++){
29. for(int x = 0; x <= fin*500;x++){
30. Compara = b1.compareTo(b2);
31. if(Compara == 1){
32.
33. b2 =
b2.multiply(Multiplicador);
34. }
35. Compara = b1.compareTo(b2);
36. if(Compara == -1){
37. b2 =
b2.divide(Multiplicador);
38. }
39. }
40. You are not allowed to view links.
Register or Login.out.println(b2);
41. i = (int)fin +1;
42. }
43.
44. You are not allowed to view links.
Register or Login bDivide = new You are not allowed to view
links. Register or Login("10");
45. long GuardarAnterior = 0;
46. long ResultadoEntero = 0;
47. for(int i = 0; i < FinalNumero;i++){
48. You are not allowed to view links.
Register or Login Resul = b1.divide(b2);
49. Resul = Resul.mod(bDivide);
50. b2 = b2.divide(bDivide);
51. ResultadoEntero = Resul.longValue();
52. GuardarAnterior = ResultadoEntero +
GuardarAnterior;
53. }
54.
55. You are not allowed to view links.
Register or Login.out.println(GuardarAnterior);
56. }
57.
58. }
59.
En línea
blozzter
Underc0der
Mensajes: 106
Actividad:
0%
Reputación 0
o
o
Creo que en tu código te complicas mucho la vida. Además de estar ilegible sucio.
Procura darle una mirada a las convenciones del lenguaje, qué dice sobre identación, nombre
de variables, nombres de clases, etc.
Código: Java
1. import java.math.BigInteger;
2.
3. public class SumaFactorial {
4.
5. public static void main(You are not allowed to view links.
Register or Login args[]){
6.
7. int numero = 100;
8.
9. You are not allowed to view links. Register or Login
factorial = calcularFactorial(numero);
10. int suma = sumarDigitos(factorial);
11.
12. You are not allowed to view links.
Register or Login.out.println(suma);
13. }
14.
15. static You are not allowed to view links.
Register or Login calcularFactorial(int numero){
16. if (numero == 1)
17. return new You are not allowed to view links.
Register or Login("1");
18. return new You are not allowed to view links.
Register or Login("" +
numero).multiply(calcularFactorial(numero-1));
19. }
20.
21. static int sumarDigitos(You are not allowed to view
links. Register or Login numero){
22. int suma = 0;
23.
24. for (You are not allowed to view links.
Register or Login c : numero.toString().toCharArray())
25. suma += You are not allowed to view links.
Register or Login.parseInt("" + c);
26.
27. return suma;
28. }
29.
30. }
31.
En línea
hackmin
Underc0der
Mensajes: 67
Actividad:
0%
Reputación 0
o
Creo que en tu código te complicas mucho la vida. Además de estar ilegible sucio.
Procura darle una mirada a las convenciones del lenguaje, qué dice sobre identación, nombre de
variables, nombres de clases, etc.
Código: Java
1. import java.math.BigInteger;
2.
3. public class SumaFactorial {
4.
5. public static void main(You are not allowed to view links.
Register or Login args[]){
6.
7. int numero = 100;
8.
9. You are not allowed to view links. Register or Login
factorial = calcularFactorial(numero);
10. int suma = sumarDigitos(factorial);
11.
12. You are not allowed to view links.
Register or Login.out.println(suma);
13. }
14.
15. static You are not allowed to view links.
Register or Login calcularFactorial(int numero){
16. if (numero == 1)
17. return new You are not allowed to view links.
Register or Login("1");
18. return new You are not allowed to view links.
Register or Login("" +
numero).multiply(calcularFactorial(numero-1));
19. }
20.
21. static int sumarDigitos(You are not allowed to view
links. Register or Login numero){
22. int suma = 0;
23.
24. for (You are not allowed to view links.
Register or Login c : numero.toString().toCharArray())
25. suma += You are not allowed to view links.
Register or Login.parseInt("" + c);
26.
27. return suma;
28. }
29.
30. }
31.
xD como que hace 1 semana empece a programar, yo lo veo bien,este si que lo veo bien
¿Cuanto llevas tu?