Aquí hay un código que escribí en Java (se ejecuta en menos de 1 segundo con bucle ingenuo)
import java.util.HashSet;
import java.util.Set;
clase pública TriangleNumber {
Loops largos privados Run = 0;
/ **
* Devuelve la lista de factores de un número
* @param number
* /
public Set factorize (número largo) {
Establezca factorSet = new HashSet ();
// Poco mejor
largo hasta la mitad = 1 + (largo) Math.ceil (Math.sqrt (número));
for (long i = 1; i <halfway; i ++) {
loopsRun ++;
if (número% i == 0) {
// i y cociente son factores
factorSet.add (i);
factorSet.add (número / i);
}
}
factor de retorno
}
/ **
* Obtenga nTh número de triángulo, n = índice
* T (n) = n (n + 1) / 2
* @param index
* @regreso
* /
public long getTriangleNumber (índice largo) {
return (índice * (índice + 1)) / 2;
}
public long getLoopsRun () {
volver bucles Ejecutar;
}
Public Void Run (int limit) {
índice largo = 1;
largo startTime = System.nanoTime ();
número largo = getTriangleNumber (índice);
factores largos = factorizar (número). tamaño ();
while (factores <= límite) {
largo transcurrido = System.nanoTime () – startTime;
if (transcurrido> = 1_000_000_000) {
System.out.println (“ElapsedTime (ns):” + transcurrido
+ “: índice:” + índice + “número:” + número + “: factores:” + factores);
}
index ++;
número = getTriangleNumber (índice);
factores = factorizar (número). tamaño ();
}
long endTime = System.nanoTime ();
long elapsedTime = endTime – startTime;
System.out.println (“ElapsedTime (ns):” + elapsedTime + “loopsRun:” + getLoopsRun ()
+ “: índice:” + índice + “número:” + número + “: factores:” + factores);
}
public static void main (String [] args) {
TriangleNumber triangles = new TriangleNumber ();
triangles.run (500);
TriangleNumberBetter trianglePrime = new TriangleNumberBetter ();
trianglePrime.run (500);
}
}
Aquí está la salida
ElapsedTime (ns): 649489562 bucles Ejecución: 54158321: índice: 12375 número: 76576500: factores: 576
- Mi hijo de 9 años está siendo intimidado, ¿qué hago?
- Soy estudiante de primer año de CS. Puedo hablar árabe “nativo” e inglés. Quiero aprender alemán o mandarín. ¿Cuál es mejor para mi?
- Mi madre sufre un terrible vacío emocional después de la muerte de mi padre. ¿Cómo puedo compensarlo?
- Quería tomar Eléctrica y Electrónica en el campus de BITS – Pilani pero obtengo un puntaje de 315 en BITSAT 2014. Entonces, ¿debería tomar Fabricación o Civil en Pilani e intentar un cambio de sucursal o EE en el campus de Goa?
- Estoy usando más de 40 subdirectorios en un sitio de viajes de WordPress (para cada destino, categoría, etc.). ¿Está bien o algo puede salir mal?
El primer número con más de 500 factores es 12.375º Triángulo.
EDITAR:
Aquí hay una mejor versión en Java (que usa la factorización de números primos para calcular directamente el número total de factores de un número dado)
importar java.util.HashMap;
import java.util.Map;
clase pública TriangleNumberBetter {
Loops largos privados Run = 0;
Mapa privado previousFactors = new HashMap ();
Mapa privado currentFactors = new HashMap ();
primos privados int [];
/ **
* Devuelve los factores totales utilizando factores de índice anteriores y actuales
* @regreso
* /
public int totalFactors () {
int total = 1;
Map totalFactors = new HashMap ();
totalFactors.putAll (previousFactors);
currentFactors.forEach ((k, v) -> {
valor int = v + totalFactors.getOrDefault (k, 0);
totalFactors.put (k, valor);
loopsRun ++;
});
// Dado que los factores totales de N (N + 1) / 2 tendrán 1 potencia menor de 2 que N * (N + 1)
if (totalFactors.get (2)! = null) {
totalFactors.put (2, totalFactors.get (2) -1);
}
for (Factores enteros: totalFactors.values ()) {
total * = (factores + 1);
loopsRun ++;
}
retorno total;
}
/ **
* Devuelve un mapa de factores primos de un número
* De forma A ^ a * B * b * C * c …
* Mapa donde A = número primo, a = exponente total
* @param number
* @regreso
* /
public Map primeFactorize (int número) {
Map primeFactors = new HashMap ();
if (número <2) {
return primeFactors;
}
largo hasta la mitad = 1 + (largo) Math.ceil (Math.sqrt (número));
for (int i = 0; i <primes.length && primes [i] <= halfway; i ++) {
int exponente = 0;
int divisor = primos [i];
while (número% divisor == 0) {
exponente ++;
divisor = divisor * primos [i];
loopsRun ++;
}
if (exponente> 0) {
primeFactors.put (primos [i], exponente);
}
loopsRun ++;
}
return primeFactors;
}
public void primeFactorizor (número int) {
previousFactors.clear ();
previousFactors.putAll (currentFactors);
currentFactors.clear ();
currentFactors.putAll (primeFactorize (número + 1));
}
/ **
* Devuelve los primeros N números primos
* @param total
* @regreso
* /
public void generatePrimeNumbers (int N) {
primos = nuevo int [N];
int primesSoFar = 0;
int número = 2;
while (primesSoFar <N) {
loopsRun ++;
if (isPrime (número)) {
primos [primesSoFar] = número;
primesSoFar ++;
}
número ++;
}
}
/ **
* Prueba si un número es primo
* @param total
* @regreso
* /
public boolean isPrime (int número) {
boolean isPrime = true;
largo hasta la mitad = 1 + (largo) Math.ceil (Math.sqrt (número));
para (largo i = 2; i <a mitad de camino; i ++) {
loopsRun ++;
if (número% i == 0 && número! = i) {
isPrime = false;
descanso;
}
}
return isPrime;
}
/ **
* Obtenga nTh número de triángulo, n = índice
* T (n) = n (n + 1) / 2
* @param index
* @regreso
* /
public long getTriangleNumber (índice largo) {
return (índice * (índice + 1)) / 2;
}
public long getLoopsRun () {
volver bucles Ejecutar;
}
Public Void Run (int limit) {
largo startTime = System.nanoTime ();
generatePrimeNumbers (1000);
int index = 1;
número largo = getTriangleNumber (índice);
factores largos = totalFactors ();
while (factores <= límite) {
largo transcurrido = System.nanoTime () – startTime;
if (transcurrido> = 1_000_000_000) {
System.out.println (“ElapsedTime (ns):” + elapsed + “loopsRun:” + getLoopsRun ()
+ “: índice:” + índice + “número:” + número + “: factores:” + factores);
}
index ++;
primeFactorizor (índice);
factores = totalFactors ();
número = getTriangleNumber (índice);
}
long endTime = System.nanoTime ();
long elapsedTime = endTime – startTime;
System.out.println (“ElapsedTime (ns):” + elapsedTime + “loopsRun:” + getLoopsRun ()
+ “: índice:” + índice + “número:” + número + “: factores:” + factores);
}
}
Este código se ejecuta en
ElapsedTime (ns): 93246660 bucles Ejecución: 444496: índice: 12375 número: 76576500: factores: 576
El número de bucles es ~ 120 veces menos y el tiempo total empleado es de aproximadamente 93 ms (aproximadamente 7 veces menos que ~ 650 ms)
EDITAR FIN
Su ciclo se ejecuta solo hasta 10,000
Además, mi código se puede optimizar aún más al memorizar los subfactores (que estoy calculando una y otra vez para cada número)
Y aquí hay un código de Python
matemáticas de importación
def factorizar (número):
factores = {}
halfway = 1 + int (math.ceil (math.sqrt (number)))
para i en rango (1, a medio camino):
if (número% i == 0):
factores [i] = verdadero
factores [número / i] = verdadero
factores de retorno
def getTriangleNumber (número):
return (número * (número + 1)) / 2
if __name__ == “__main__”:
índice = 1
número = getTriangleNumber (índice)
factores = len (factorizar (número))
mientras que los factores <= 500:
índice + = 1
número = getTriangleNumber (índice)
factores = len (factorizar (número))
imprimir “Índice:% d, Número% d, Factores:% d”% (índice, número, factores)
que se ejecuta en unos 4 segundos
time python ~ / Desktop / triangleNumber.py
Índice: 12375, número 76576500, factores: 576
0m3.873s reales
usuario 0m3.776s
sys 0m0.045s