3
\$\begingroup\$

Good day, it's my first time doing something like this so I wanted to solve some of the challenges on project Euler, however I reached a block on my code, even before I submitted I was aware that I would be unable to compile within time limits for numbers well beyond the million or close to a million, still went along with it and of course, the test cases on the million(s)? [because they are hidden and I dont exactly know the numbers] expired due to time limits constraints.

I was wondering if I could receive some feedback on how to improve my code, given that at the minimum the value received would be a million of course.

class Solution {

    private static void mathSolver(long _number){
        long _sum = 0;

        for(long x = 0; x<_number; x++){
            if((x % 3 == 0) || (x % 5 == 0)){
                _sum += x;
            }
        }
        Console.WriteLine(_sum);
    }

    static void Main(String[] args) {
        int t = Convert.ToInt32(Console.ReadLine());
        for(int a0 = 0; a0 < t; a0++){
            int n = Convert.ToInt32(Console.ReadLine());
            mathSolver(n);
        }
    }
}

I already tried of tinkering with it with some math sequences, trying to figure out a pattern that would allow me to jump between numbers, so that instead of iterating through every number on a million, I would, lets say, jump between 3's or 5s directly, however no operation that I could think of would give me the result I wanted as it was very prone to mistakes along the way.

A slight background of me if anyone is interested while reviewing, I'm not exactly new to C#, been doing it for slightly under 2 years however my first employer procured tons of bad practices and code disasters, this is why I want to expose myself to these kind of things, to improve efficiency while coding, to get better code readibility and presentation as well as trying to find solutions that aren't as forceful.

Thank you for your answers and may you have a nice day!

\$\endgroup\$
2
\$\begingroup\$

Hint:

$$ \sum_{i=1}^ni = \frac{n (n+1)}{2} $$

With this you can compute the sum of 1 to n without looping. Can you figure out a way to do this for all digits with increments of 3? And 5?

The last thing to consider is that with this method, you are counting all digits divisible by 15 double, since they are both divisible by 3 and 5.

\$\endgroup\$
  • \$\begingroup\$ Thank you, I managed to solve this by using the math provided, it was very hard to understand at first so I checked for other sources, one of them explained the formula on detail, I'll annex the answer below as an answer to the question, it would be my pleasure if you could pin point me my mistakes! Thank you very much !! \$\endgroup\$ – Eduardo Oct 3 at 23:31
1
\$\begingroup\$

I managed to solve it using the Math formulas both provided by user JAD, MJOLKA and Emily L.

It's not pretty looking but tried to make it functional while retaining versatility as to modifications, a single method also means it can be re-used to determine different values since I left things a bit abstract and the behavior determined by the parameters sent.

class Solution {

    private static long mathSolver(long _endNumber){
        long _firstDivision = 0, _secondDivision = 0, _thirdDivision = 0;
        //We search for individual values
        _firstDivision = Division(_endNumber, 3, 1);
        _secondDivision = Division(_endNumber, 5, 5);
        _thirdDivision = Division(_endNumber, 15, 15);

        return _firstDivision + _secondDivision - _thirdDivision;
    }


    private static long Division(long _endNumber, int _divider, int _substracter){
        //We search for residues, if they dont exist we apply our own
        long _division = 0;
        if(_endNumber % _divider == 0){ 
            _division = (_endNumber - _substracter)/_divider;
        }
        else{
            _division = (_endNumber- (_endNumber % _divider))/_divider;
        }
        return (_divider*((_division)*((_division +1))/2));
    }

    static void Main(String[] args) {
        long t = Convert.ToInt64(Console.ReadLine());
        for(int a0 = 0; a0 < t; a0++){
            long n = Convert.ToInt64(Console.ReadLine());
            long _sum = mathSolver(n);
            Console.WriteLine(_sum);
        }
    }
}

It was very entertaining and I will check for more challenges whenever I have the time for them! you learn a lot of math-related subjects to make your code efficient!

\$\endgroup\$
  • 2
    \$\begingroup\$ I have taken the liberty to remove the “request for feedback” from your answer. If that is desired then you should post a follow-up question. \$\endgroup\$ – Martin R Oct 4 at 8:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.