skip to Main Content

To preface, I am using Visual Studio 2022. The problem on Project Euler states:

If we list all the natural numbers below 10
that are multiples of 3
or 5, we get 3, 5, 6, and 9. The sum of these multiples is 23. Find the sum of all the multiples of 1000
or
below.

I have done most of the debugging of my code myself after hours, but cannot figure this small thing out. I also asked a friend that had solved this herself, and she was confused as to why it wasn’t correct after comparing it to her own working code.

This is my code:

int x = 0, y = 0, totalSum = 0;

//multiples of 3
for (int i = 0; x < 1000; i++)
{
    x = 3 * i;

    if (x % 5 != 0)
    {
        totalSum += x;
        Console.WriteLine(totalSum);
    }
}

//multiples of 5
for (int n = 0; y < 1000; n++)
{
    y = 5 * n;

    totalSum += y;
    Console.WriteLine(totalSum);
}

Console.WriteLine(totalSum);

Console.ReadKey();

When ran, the console outputs 235,170. I looked up the correct answer after pulling my hair out, and I know the answer is 233,168. I just can’t figure out how to get there. Curiously, when I change the top for loop to . . .

for (int i = 0; x < 996; i++)
{
    x = 3 * i;

    if (x % 5 != 0)
    {
        totalSum += x;
        Console.WriteLine(totalSum);
    }
}

. . . it outputs 233,169. One off. I’m incredibly confused as to what is going on. I’m incredibly new to programming – having only been doing it for about a month here and there, so I apologize if my code isn’t the most optimal. Would appreciate the help, thanks in advance!

2

Answers


  1. Chosen as BEST ANSWER
    for (int i = 0; x < 999; i++)
    {
        x = 3 * i;
    
        if (x % 5 != 0)
        {
            sumOfX += x;
            Console.WriteLine(x);
        }
    }
    
    //multiples of 5
    for (int n = 0; y < 995; n++)
    {
        y = 5 * n;
    
        sumOfY += y;
        Console.WriteLine(y);
    }
    

    I figured out it was going one multiple over because of how the loop checks at the beginning. E.g. 5x199 is still less than 1000, and so the loop keeps going and does 5x200, going over the limit I thought I set. I changed the loops accordingly. I thought it was more complicated than it actually was. Thanks for the help.


  2. First to congratulate you: nice job catching the 15 case with mod (%)! The error does not lie here.

    I believe the error lies in the

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

    and

    for (int n = 0; y < 1000; n++)
    

    lines.

    You see, you can think of a for-loop of form

    for(variable declaration; condition check; variable change) {
       body();
    }
    

    as

    variable declaration;
    while(condition check) {
       body();
       variable change;
    }
    

    In your code, you use i and n as the variables to keep track of iteration, but use x and y as the condition check, so to speak. This leads to those loops running once more. Why?

    The thing is, consider the last couple test cases… when does the for-loop summing 3s stop? You would think on 999 because 1002 is greater than 1000. However, after

    Console.WriteLine(totalSum);
    

    line, the variable i will increment to 334… but will not stop the loop because value of x is still 999. So the following body() will run once more, i will increment to 335, AND THEN the loop will stop as 1002 > 1000.

    NOTE: You may have been able to catch this error by looking at a Console.WriteLine("i: " + i + " x: " + x); somewhere in there. This issue is often called an off-by-one error. In general, it takes scrupulously examining the beginning and ending of the loop through printing or other means (stepping through in a debugger, perhaps?) to catch these.

    While you could add another if-statement to the end with a check like

    if(x == 999) {
        break;
    }
    

    This is redundant, and actually hurts the understanding, and re-usability of the code.

    In general, I will leave you with this: as a beginner, don’t use another variable in the condition check than the one that you declare. This may lead to creeping little bugs like the one I explain above (the off-by-one error).

    HINT: You could refactor it to use i for the condition check (perhaps integer division may be of use here?) or x, both requiring a little bit of refactoring.

    That said, as a beginner, I don’t want to give the answer away to you! I hope the above advice, and perhaps a little more bashing, will help lead you to the correct solution.

    Happy Problem Solving!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search