Encuentra la sum de todos los múltiplos de 3 o 5 debajo de 1000

Si enumeramos todos los números naturales por debajo de 10 que son múltiplos de 3 o 5, obtenemos 3, 5, 6 y 9. La sum de estos múltiplos es 23. Tengo el siguiente código pero la respuesta no coincide.

#include int main() { long unsigned int i,sum=0; clrscr(); for(i=0;i<=1000;i++) { if((i%5==0)||(i%3==0)) { sum=sum+1; } } printf("%d\n",sum); getchar(); return 0; } 

Dos cosas:

  • estás incluyendo 1000 en el bucle, y
  • está agregando uno a la sum cada vez, en lugar del valor en sí.

Cambiar el bucle a

 for(i=0;i<1000;i++) 

Y la línea de sum para

 sum=sum+i; 

En lugar de utilizar soluciones basadas en rango / bucle, es posible que desee aprovechar más las matemáticas que la fuerza bruta.

Hay una forma sencilla de obtener la sum de los múltiplos de un número, menos que un número.

Por ejemplo, la sum de los múltiplos de 3 hasta 1000 es: 3 + 6 + 9 + … + 999, que puede reescribirse como: 3 * (1 + 2 + 3 + … + 333)

Hay una manera simple de resumir todos los números 1-N:

 Sum(1,N) = N*(N+1)/2 

Así que una función de ejemplo sería

 unsigned int unitSum(unsigned int n) { return (n*(n+1))/2; } 

Así que ahora se han reducido todos los múltiplos de 3 menos que 1000 (alias hasta 999 inclusive) a:

 3*unitSum((int)(999/3)) 

Puedes hacer lo mismo con múltiplos de 5:

 5*unitSum((int)(999/5)) 

¡Pero hay una advertencia! Ambos cuentan múltiplos de ambos, como 15, 30, etc. Los cuenta dos veces, uno para cada uno. Entonces para equilibrar eso, se resta una vez.

 15*unitSum((int)(999/15)) 

Entonces, en total, la ecuación es:

 sum = 3*unitSum((int)(999/3)) + 5*unitSum((int)(999/5)) - 15*unitSum((int)(999/15)) 

Así que ahora, en lugar de repasar un gran número de números y hacer comparaciones, ¡simplemente estás haciendo una simple multiplicación!

Tal vez deberias hacer

 sum += i // or sum = sum + i 

en lugar de

 sum = sum + 1 

Además, tenga cuidado cuando imprima long unsigned int con printf. Supongo que el especificador correcto es %lu .

Debe ser sum = sum + i lugar de 1 .

 #include #include int main() { int x,y,n; int sum=0; printf("enter the valeus of x,y and z\n"); scanf("%d%d%d",&x,&y,&n); printf("entered valeus of x=%d,y=%d and z=%d\n",x,y,n); sum=x*((n/x)*((n/x)+1)/2)+y*((n/y)*((n/y)+1)/2)-x*y*(n/(x*y))*((n/(x*y))+1)/2; printf("sum is %d\n",sum); return 0; } // give x,y and n as 3 5 and 1000 

Aquí hay una línea de python que da la respuesta correcta (233168):

 reduce( lambda x,y: x+y, [ x for x in range(1000) if x/3.0 == int( x/3.0 ) or x/5.0 == int( x/5.0 ) ] ) 

Al igual que una mejora, es posible que desee evitar el bucle por completo:

 multiples of 3 below 1000 form an AP : 3k where k in [1, 333] multiples of 5 below 1000 form an AP : 5k where k in [1, 199] 

Si evitamos los múltiplos de 3 y 5: 15k donde k en [1, 66]

So the answer is : 333*(3+999)/2 + 199(5+995)/2 - 66*(15+990)/2 = 2331 68

¿Por qué querrías hacer esto? Te queda por descubrir.

Hecho interesante de la diferencia de tiempo entre estos 2 métodos … El segundo método solo calcula con los números necesarios y no itera a través de un bucle. Ejemplo: 3 * (1 + 2 + 3 + 4 … 333) (porque 3 * 333 = 999 y 999 <1000.

  static void Main(string[] args) { Stopwatch sw = new Stopwatch(); Calc calculator = new Calc(); long target = 999999999; sw.Start(); Console.WriteLine("Result: " + (calculator.calcMultipleSumFast(3,target) + calculator.calcMultipleSumFast(5, target) - calculator.calcMultipleSumFast(15, target))); sw.Stop(); Console.WriteLine("Runtime: " + sw.Elapsed); Console.WriteLine(); sw.Start(); Console.WriteLine("Result: " + (calculator.calcMultiplesSum(3, 5,1000000000))); sw.Stop(); Console.WriteLine("Runtime: " + sw.Elapsed); Console.ReadKey(); } public class Calc { public long calcMultiplesSum(long n1, long n2, long rangeMax) { long sum = 0; for (long i = 0; i < rangeMax; i++) { if ((i % n1 == 0) || (i % n2 == 0)) { sum = sum + i; } } return sum; } public long calcMultipleSumFast(long n, long rangeMax) { long p = rangeMax / n; return (n * (p * (p + 1))) / 2; } } 

introduzca la descripción de la imagen aquí

Puede comenzar por una iteración de 3 a 1000 en pasos de 3 (3,6,9,12, etc.), agregándolos a la sum como,

 int i = 3, sum = 0; for (; i < 1000; i += 3) { sum += i; } 

Luego, podría iterar de 5 a 1000 por 5 (omitiendo múltiplos de 3 porque ya se han agregado), agregando esos valores a la sum también.

 for (i = 5; i < 1000; i += 5) { if (i % 3 != 0) sum += i; } 

Luego muestra la sum

 printf("%d\n", sum); 

Implementación Python del problema. Corto, preciso y gordo.

 sum=0 for i in range(1000): if (i%3==0) or (i%5==0): sum=sum+i print sum 
 int Sum(int N) { long long c = 0; N--; //because you want it less than 1000 if less than or equal delete this line int n = N/3,b = N/5,u = N/15; c+= (n*(n+1))/2 * 3; c+= (b*(b+1))/2 * 5; c-= (u*(u+1))/2 * 15; return c; } 

Usando el enfoque de pasos, puedes hacer una versión:

 #include  int main ( void ) { int sum = 0; for (int i = 0; i < 1000; i += 5) { sum += i; } for (int i = 0; i < 1000; i += 3) { if (i % 5) sum += i; /* already counted */ } printf("%d\n", sum); return 0; } 

Lo que hace mucho menos cálculos de modulo .

De hecho, con un contador, puedes hacer una versión con ninguna:

 #include  int main ( void ) { int sum = 0; int cnt = 6; for (int i = 0; i < 1000; i += 5) { sum += i; } for (int i = 0; i < 1000; i += 3) { if (--cnt == 0) cnt = 5; else sum += i; } printf("%d\n", sum); return 0; } 
 int main(int argc, char** argv) { unsigned int count = 0; for(int i = 1; i < 1001; ++i) if(!(i % 3) && !(i % 5)) count += i; std::cout << i; return 0; } 
 package com.venkat.test; public class CodeChallenge { public static void main(String[] args) { int j, sum=0; for ( j = 0; j <=1000; j++) { if((j%5==0)||(j%3==0)) { sum=sum+j; } } System.out.println(sum); } }