1

Add all the values between 100 and 4000000 inclusively that are divisable by 3 or 5 but not both 3 and 5

Can't figure out how to implement second part of that stipulation. Here's what I have so far:

var sum = 0;
for (var i = 100; i < 4000001; i++) {
    if (i % 3 || i % 5 === 0) {
        sum = sum + i;
    } 
}
Rory Perro
  • 441
  • 2
  • 7
  • 16
  • What language is this? What does the expression `i % 3 || i % 5 === 0` mean? It looks a bit suspicious to me. In any case, assuming that you have `A || B` right, what you actually need is "exclusive OR", or "XOR": `A && !B || !A && B`. – Dialecticus Aug 22 '15 at 09:10
  • I misstyped. should be i % 3 === 0 – Rory Perro Aug 22 '15 at 10:29

4 Answers4

6

You can compute the sum without any loop, using the formula for the sum of an arithmetic progression: We have

    3 + 5 + 6 + 9 + 10 + 12 + 18 + 20 + ...
=   3 + 6 + 9 + 12 + 15 + 18 + ...
  + 5 + 10 + 15 + 20 + ...
  - 2*(15 + 30 + 45 + ...)

Note that we add all the multiples of 3 and 5 but then subtract the multiples of 15 twice, because they were counted twice as multiples of both 3 and 5.

Let g(n) be the sum of integers from 1 to n. We have g(n) = n*(n+1)/2.

Let f(n) be the sum of integers between 1 and n that are divisible by 3 or 5, but not both. Then we have

f(n) = 3*g(floor(n / 3)) + 5*g(floor(n/5)) - 30*g(floor(n/15))

And the sum of integers between m and n that are divisible by 3 or 5, but not both is then just f(n) - f(m - 1). This can be computed in O(1).

Niklas B.
  • 92,950
  • 18
  • 194
  • 224
  • (+1) but I'm voting to close both the question and answer since this whole thing is about math and not programming and belongs on another stackexchange site. Just kidding. – גלעד ברקן Aug 22 '15 at 19:07
2

You simply need to escape only those part which involves division by 15, and other higher numbers(multiple of 15) will be avoided further automatically.

Note that checking divisibility by 15 should be at the top, which on being true will continue further iteration without executing the below codes of divisibility by 3 and 5. If false, then a number can only be divisible by 3 or 5 or none, but not both.

for (var i = 100; i < 4000001; i++) {
   if(i % 15 == 0 )
    continue;
   if (i % 3  == 0) {
    sum = sum + i;
   } 
   if (i % 5  == 0) {
    sum = sum + i;
   } 
}

Also, note that you have used === operator which I don't think is a valid operator, probably you want ==. BTW, I am not sure whether any language supports ===, I think Javascript supports that. So, be careful at that step.

Am_I_Helpful
  • 18,735
  • 7
  • 49
  • 73
1

You can use != instead of || since this is exactly what you want. Only divisible by 3 or 5 but not by both.

var sum = 0;
for (var i = 100; i < 4000001; i++) {
    if ((i % 3 == 0) != (i % 5 == 0)) {
        sum = sum + i;
    } 
}
Qbyte
  • 12,753
  • 4
  • 41
  • 57
0
var sum = 0;
for (var i = 100; i < 4000001; i++) {
    if (i % 3 === 0 ^ i % 5 === 0) {
       sum = sum + i;
   } 
}

use the exclusive OR , XOR ^ returns true only when one of the conditions not both is true.

  • Operator `^` usually denotes binary XOR, not logical XOR, and should not be mixed with other logical operators. I don't know what operator `===` stands for, so beware of potential errors and undefined behaviors. – Dialecticus Aug 22 '15 at 09:53
  • Dialecticus ^ denotes Exclusive OR which is logical exclusive not binary exclusive or, also === in Javascript checks for type and value equaity. Only when i % 3 is 0 or i % 5 is equal to zero will it pass. if it is undefined it won't – Jideobi Benedine Ofomah Aug 22 '15 at 09:56
  • In what language does `^` denotes a logical XOR? In all C-like languages (C, C++, C#, Java, JavaScript) it's bitwise (binary) XOR. I mentioned undefined behavior because `^` is bitwise XOR, and `===` probably does not return bitwise result. – Dialecticus Aug 22 '15 at 10:08
  • http://stackoverflow.com/questions/726652/creating-a-logical-exclusive-or-operator-in-java ^ is and can also be used as a logical XOR operator or as a bitwise XOR operator. it is simple, test the code and see for yourself. – Jideobi Benedine Ofomah Aug 22 '15 at 10:11
  • They talk about Java. So okay, in Java `^` is overloaded so it's also logical XOR. But what if the language of OP's code is not Java? – Dialecticus Aug 22 '15 at 10:19
  • Hey, you are right, my solution is language dependent, – Jideobi Benedine Ofomah Aug 22 '15 at 10:25
  • @Dialecticus It looks like JavaScript to me. In JavaScript, `^` converts the LHS and RHS to integers and then performs a bitwise XOR. For booleans, that means the result is the same as for a logical XOR, except that `false` gets mapped to `0`, and `true` gets mapped to `1`. In an `if` condition, both `0` and `false` cause the block to be skipped, so that distinction does not matter. –  Aug 22 '15 at 10:25
  • That said, I would prefer writing it as `if ((i % 3 === 0) !== (i % 5 === 0))`, as I think it is easier to understand, but that is highly subjective. –  Aug 22 '15 at 10:27