Project Euler #1 in C++ Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?Project Euler #1 in PHPProject Euler #1 in JavaProject Euler RetreatProject Euler #1: Multiples of 3 and 5Project Euler Problems #1-#5Project Euler #1Project Euler #1 - RevisitedProject Euler 1 in JavaProject Euler problem #1 in Python 3Python sum of multiples of some numbers in a range

Flight departed from the gate 5 min before scheduled departure time. Refund options

Why is a lens darker than other ones when applying the same settings?

My mentor says to set image to Fine instead of RAW — how is this different from JPG?

Getting out of while loop on console

What is the difference between CTSS and ITS?

What is the "studentd" process?

Tannaka duality for semisimple groups

Resize vertical bars (absolute-value symbols)

Why are vacuum tubes still used in amateur radios?

The Nth Gryphon Number

What is a more techy Technical Writer job title that isn't cutesy or confusing?

Is multiple magic items in one inherently imbalanced?

As a dual citizen, my US passport will expire one day after traveling to the US. Will this work?

How to change the tick of the color bar legend to black

What is the difference between a "ranged attack" and a "ranged weapon attack"?

Found this skink in my tomato plant bucket. Is he trapped? Or could he leave if he wanted?

What is the chair depicted in Cesare Maccari's 1889 painting "Cicerone denuncia Catilina"?

How does the math work when buying airline miles?

Monty Hall Problem-Probability Paradox

Why is std::move not [[nodiscard]] in C++20?

How does light 'choose' between wave and particle behaviour?

Moving a wrapfig vertically to encroach partially on a subsection title

What does 丫 mean? 丫是什么意思?

Is CEO the "profession" with the most psychopaths?



Project Euler #1 in C++



Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Announcing the arrival of Valued Associate #679: Cesar Manara
Unicorn Meta Zoo #1: Why another podcast?Project Euler #1 in PHPProject Euler #1 in JavaProject Euler RetreatProject Euler #1: Multiples of 3 and 5Project Euler Problems #1-#5Project Euler #1Project Euler #1 - RevisitedProject Euler 1 in JavaProject Euler problem #1 in Python 3Python sum of multiples of some numbers in a range



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








19












$begingroup$


I'm learning C++ and currently doing Project Euler challenges. The first challenge is the following.




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 3 or 5 below 1000.




I did a quite simple and stupid brute-force implementation by just looping from 1 to 999, checking if its divisible by either 3 or 5 and if it is, sum it with the result variable.



Is there any faster/better/cleaner implementation, maybe without a loop or with less division?



#include <iostream>

int main(int argc, char *argv[])

int result(0);
for (int i = 1; i < 1000; ++i)
if (!(i % 3 && i % 5))
result += i;


std::cout << "Result: " << result << "n";
return 0;










share|improve this question









New contributor




o2640110 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$







  • 9




    $begingroup$
    The thing about Euler tests is that they are trying to make you think smart. Yes you can brute force this even for large values of n but there should be an elegant solution that even a human could do. It is learning these tricks that will help you in later tests were a brute force attack on the problem is not feasible.
    $endgroup$
    – Martin York
    2 days ago






  • 3




    $begingroup$
    Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    $endgroup$
    – Mast
    2 days ago






  • 1




    $begingroup$
    int result(0); and int result=0; are the same, but the latter is more clear (to me at least)
    $endgroup$
    – Stefan
    yesterday

















19












$begingroup$


I'm learning C++ and currently doing Project Euler challenges. The first challenge is the following.




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 3 or 5 below 1000.




I did a quite simple and stupid brute-force implementation by just looping from 1 to 999, checking if its divisible by either 3 or 5 and if it is, sum it with the result variable.



Is there any faster/better/cleaner implementation, maybe without a loop or with less division?



#include <iostream>

int main(int argc, char *argv[])

int result(0);
for (int i = 1; i < 1000; ++i)
if (!(i % 3 && i % 5))
result += i;


std::cout << "Result: " << result << "n";
return 0;










share|improve this question









New contributor




o2640110 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$







  • 9




    $begingroup$
    The thing about Euler tests is that they are trying to make you think smart. Yes you can brute force this even for large values of n but there should be an elegant solution that even a human could do. It is learning these tricks that will help you in later tests were a brute force attack on the problem is not feasible.
    $endgroup$
    – Martin York
    2 days ago






  • 3




    $begingroup$
    Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    $endgroup$
    – Mast
    2 days ago






  • 1




    $begingroup$
    int result(0); and int result=0; are the same, but the latter is more clear (to me at least)
    $endgroup$
    – Stefan
    yesterday













19












19








19


2



$begingroup$


I'm learning C++ and currently doing Project Euler challenges. The first challenge is the following.




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 3 or 5 below 1000.




I did a quite simple and stupid brute-force implementation by just looping from 1 to 999, checking if its divisible by either 3 or 5 and if it is, sum it with the result variable.



Is there any faster/better/cleaner implementation, maybe without a loop or with less division?



#include <iostream>

int main(int argc, char *argv[])

int result(0);
for (int i = 1; i < 1000; ++i)
if (!(i % 3 && i % 5))
result += i;


std::cout << "Result: " << result << "n";
return 0;










share|improve this question









New contributor




o2640110 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$




I'm learning C++ and currently doing Project Euler challenges. The first challenge is the following.




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 3 or 5 below 1000.




I did a quite simple and stupid brute-force implementation by just looping from 1 to 999, checking if its divisible by either 3 or 5 and if it is, sum it with the result variable.



Is there any faster/better/cleaner implementation, maybe without a loop or with less division?



#include <iostream>

int main(int argc, char *argv[])

int result(0);
for (int i = 1; i < 1000; ++i)
if (!(i % 3 && i % 5))
result += i;


std::cout << "Result: " << result << "n";
return 0;







c++ beginner programming-challenge






share|improve this question









New contributor




o2640110 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




o2640110 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 2 days ago









Rakete1111

2,2641822




2,2641822






New contributor




o2640110 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 2 days ago









o2640110o2640110

13718




13718




New contributor




o2640110 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





o2640110 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






o2640110 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







  • 9




    $begingroup$
    The thing about Euler tests is that they are trying to make you think smart. Yes you can brute force this even for large values of n but there should be an elegant solution that even a human could do. It is learning these tricks that will help you in later tests were a brute force attack on the problem is not feasible.
    $endgroup$
    – Martin York
    2 days ago






  • 3




    $begingroup$
    Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    $endgroup$
    – Mast
    2 days ago






  • 1




    $begingroup$
    int result(0); and int result=0; are the same, but the latter is more clear (to me at least)
    $endgroup$
    – Stefan
    yesterday












  • 9




    $begingroup$
    The thing about Euler tests is that they are trying to make you think smart. Yes you can brute force this even for large values of n but there should be an elegant solution that even a human could do. It is learning these tricks that will help you in later tests were a brute force attack on the problem is not feasible.
    $endgroup$
    – Martin York
    2 days ago






  • 3




    $begingroup$
    Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    $endgroup$
    – Mast
    2 days ago






  • 1




    $begingroup$
    int result(0); and int result=0; are the same, but the latter is more clear (to me at least)
    $endgroup$
    – Stefan
    yesterday







9




9




$begingroup$
The thing about Euler tests is that they are trying to make you think smart. Yes you can brute force this even for large values of n but there should be an elegant solution that even a human could do. It is learning these tricks that will help you in later tests were a brute force attack on the problem is not feasible.
$endgroup$
– Martin York
2 days ago




$begingroup$
The thing about Euler tests is that they are trying to make you think smart. Yes you can brute force this even for large values of n but there should be an elegant solution that even a human could do. It is learning these tricks that will help you in later tests were a brute force attack on the problem is not feasible.
$endgroup$
– Martin York
2 days ago




3




3




$begingroup$
Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
$endgroup$
– Mast
2 days ago




$begingroup$
Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
$endgroup$
– Mast
2 days ago




1




1




$begingroup$
int result(0); and int result=0; are the same, but the latter is more clear (to me at least)
$endgroup$
– Stefan
yesterday




$begingroup$
int result(0); and int result=0; are the same, but the latter is more clear (to me at least)
$endgroup$
– Stefan
yesterday










4 Answers
4






active

oldest

votes


















21












$begingroup$

The code is basically fine.



The if condition is perhaps a little complicated though. To interpret it you have to read "if not ((i is not a multiple of 3) and (i is not a multiple of 5))", which is a double negative.



Given the problem statement, we'd expect something more like "if (i is a multiple of 3) or (i is a multiple of 5)", so:



if ((i % 3 == 0) || (i % 5 == 0))


Nitpicking:



  • If we don't need argc and argv, we can declare main as int main() with no arguments.

  • The return 0; at the end of main happens automatically in C++, so we don't have to write it ourselves.


Note that there exists an arithmetic solution to the problem, which is much faster (it could even be done at compile-time in C++).




We want to sum all the multiples of 3 or 5 less than 1000. We can think about the sequence of multiples of 3 as (3, 6, 9, 12, 15, ..., 999), which is the same as 3 * (1, 2, 3, 4, 5, ..., 333). [...]



Such a sequence, where the difference between each number is constant, is called a finite arithmetic progression [and the sum is] a finite arithmetic series. The formula for the sum is 1/2 * n * (a_1 + a_n). where n is the number of terms being added, a_1 is the first element in the sequence, and a_n is the last element in the sequence.







share|improve this answer









$endgroup$








  • 3




    $begingroup$
    Even the brute-force formula could easily be done at compile-time, though it's slightly more unwieldy.
    $endgroup$
    – Deduplicator
    2 days ago






  • 1




    $begingroup$
    Is there a difference in speed by not adding argv and argc?
    $endgroup$
    – o2640110
    2 days ago











  • $begingroup$
    @o2640110 No there is not. :)
    $endgroup$
    – Rakete1111
    2 days ago






  • 1




    $begingroup$
    The arithmetic solution could be done at compile time, or even worked out on a 4-op calculator.
    $endgroup$
    – Laurent LA RIZZA
    yesterday



















17












$begingroup$

Yes, there are ways to do this that avoid most of the divisions, and are probably faster as well.



Let's start with a simplified version of the problem: add up all the multiples of 3.



Now, you could do a simplified version of what you've written:



int sum = 0;

for (int i=1; i<1000; i++)
if (i % 3 == 0)
sum += i;


...but we know up front that 1 and 2 aren't multiples of three. We can generate all multiples of three by counting by 3's:



int sum = 0;

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


Obviously enough, we can do the same thing for multiples of 5:



int sum = 0;

for (int i=0; i<1000; i += 5)
sum += i;


But if we do both in succession:



int sum = 0;

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

for (int i=0; i<1000; i += 5)
sum += i;


...we'll get the wrong answer. The problem now is that if a number is a multiple of both 3 and 5 (e.g., 15) we've counted it twice. There are a few ways we can avoid that. One is to have the second loop add i to the sum if and only if i is not a multiple of 3.



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


Another is to initially add those, but then add a third loop that generates only the numbers that are multiples of both 3 and 5, and subtracts those from the overall result:



int product = 3 * 5;

for (int i = 0; i < 1000; i += product)
sum -= i;


Since you're (apparently) more interested in learning programming than in learning math, I'll only sketch out the next step. There are ways to avoid doing those loops at all though. What we're really doing is (for two different values of N) summing a series of 1N + 2N + 3N + 4N + ...



Using the distributive property, we can turn that into N * (1 + 2 + 3 + 4 + ...). Gauss invented an easy way to sum a series like 1 + 2 + 3 + 4 + ..., so what we need to do is compute the number of terms of that series we need for each of 3 and 5, compute them, multiply by 3 and 5 respectively, and add together the results. Then do the same for multiples of 15, and subtract that from the result. The number of terms in each series we need will be the upper limit divided by the N for that series--so for multiples of 3, we have 1000/3 terms, and for multiples of 5 we have 1000/5 terms.



So, we can compute the final value as:



3 * gauss_sum(1000/3) + 5 * gauss_sum(1000/5) - 15 * gauss_sum(1000/15)


...and we're left with no loops at all, so we can compute the correct value for any upper limit (up to what fits in an unsigned long long, anyway) in constant time.






share|improve this answer











$endgroup$




















    11












    $begingroup$

    The one bit that is absolutely not fine is this line:



    if (!(i % 3 && i % 5))


    It is clever, and clever is bad. The question was about "all integers that are multiples of 3 or 5." So write that:



    if (i % 3 == 0 || i % 5 == 0)





    share|improve this answer









    $endgroup$








    • 1




      $begingroup$
      +1! Any time you write code that has to be deciphered, you should change it to something that can be read. To be honest, half the time, I'd take it a step further, and actually put i%3 into a variable: divisibleBy3. That way, the IF statement is simply if (divisbleBy3 || divisibleBy5) - doesn't get much more readable than that.
      $endgroup$
      – Kevin
      yesterday






    • 2




      $begingroup$
      @Kevin: Another possibility would be to define a lambda like: auto divisibleBy = [](int x, int y) return x % y == 0; ; Then you'd just use: if (divisibleBy(i, 3) || divisibleBy(i, 5)) ...
      $endgroup$
      – Jerry Coffin
      yesterday










    • $begingroup$
      Just to add to this, you can see the compiler output here. godbolt.org/z/lAws-Z At least for this compiler (clang 7, fully optimised) the two versions compile to exactly the same thing. That all to say, it's OK to use the readable version over what you expect is more efficient: the compiler knows better than almost any human programmer what will be efficient.
      $endgroup$
      – Josiah
      16 hours ago


















    0












    $begingroup$

    As you were asking for "less division"... Here's a different approach with absolutely no division, multiplication or modulo operations. We have two counters t (for increment three) and f (for increment five), and update them in a single while loop. Due to the increments it's guaranteed t and f will always be numbers divisible by 3 resp. 5. Now we just have to pick which counter to update (the lower one), and to handle the case when both counters occasionally meet :)



    (You can avoid the std::min-line and put the addition to result into the if/else if/else-part, but with this it's easier to understand what happens.)



    #include <iostream>

    int main()
    unsigned t=0, f=0;
    unsigned result=0;
    while (t<1000)
    result+=std::min(t, f);

    if (t<f) t+=3;
    else if (f<t) f+=5;
    else // f==t
    t+=3;
    f+=5;


    std::cout << "Result: " << result << std::endl;
    return(0);






    share|improve this answer









    $endgroup$












    • $begingroup$
      You know that return is not a function? That can be crucial in C++ when the return-type is deduced with decltype(auto).
      $endgroup$
      – Deduplicator
      6 hours ago










    • $begingroup$
      Yes I know that. @Deduplicator, do you have an example where brackets actually do change the return type?
      $endgroup$
      – jvb
      6 hours ago










    • $begingroup$
      As I said, additional parentheses around the return-expression are meaningful when the return-type is deduced with decltype(auto).
      $endgroup$
      – Deduplicator
      4 hours ago










    • $begingroup$
      Ok, so the deduced function types indeed would be T() vs T&() in your example - actually different in regards to std::type_info, but only in this aspect - and neither deduced type is technically incorrect or leads to erroneous behaviour. As a consequence, I wouldn't encourage comparing type info obtained with auto :)
      $endgroup$
      – jvb
      1 hour ago










    • $begingroup$
      std::type_info (returned by typeid) only knows fully decayed types. And if i was not a global, but e.g. a local or parameter, the difference between a copy and a reference may be more relevant.
      $endgroup$
      – Deduplicator
      50 mins ago












    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );






    o2640110 is a new contributor. Be nice, and check out our Code of Conduct.









    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217660%2fproject-euler-1-in-c%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    21












    $begingroup$

    The code is basically fine.



    The if condition is perhaps a little complicated though. To interpret it you have to read "if not ((i is not a multiple of 3) and (i is not a multiple of 5))", which is a double negative.



    Given the problem statement, we'd expect something more like "if (i is a multiple of 3) or (i is a multiple of 5)", so:



    if ((i % 3 == 0) || (i % 5 == 0))


    Nitpicking:



    • If we don't need argc and argv, we can declare main as int main() with no arguments.

    • The return 0; at the end of main happens automatically in C++, so we don't have to write it ourselves.


    Note that there exists an arithmetic solution to the problem, which is much faster (it could even be done at compile-time in C++).




    We want to sum all the multiples of 3 or 5 less than 1000. We can think about the sequence of multiples of 3 as (3, 6, 9, 12, 15, ..., 999), which is the same as 3 * (1, 2, 3, 4, 5, ..., 333). [...]



    Such a sequence, where the difference between each number is constant, is called a finite arithmetic progression [and the sum is] a finite arithmetic series. The formula for the sum is 1/2 * n * (a_1 + a_n). where n is the number of terms being added, a_1 is the first element in the sequence, and a_n is the last element in the sequence.







    share|improve this answer









    $endgroup$








    • 3




      $begingroup$
      Even the brute-force formula could easily be done at compile-time, though it's slightly more unwieldy.
      $endgroup$
      – Deduplicator
      2 days ago






    • 1




      $begingroup$
      Is there a difference in speed by not adding argv and argc?
      $endgroup$
      – o2640110
      2 days ago











    • $begingroup$
      @o2640110 No there is not. :)
      $endgroup$
      – Rakete1111
      2 days ago






    • 1




      $begingroup$
      The arithmetic solution could be done at compile time, or even worked out on a 4-op calculator.
      $endgroup$
      – Laurent LA RIZZA
      yesterday
















    21












    $begingroup$

    The code is basically fine.



    The if condition is perhaps a little complicated though. To interpret it you have to read "if not ((i is not a multiple of 3) and (i is not a multiple of 5))", which is a double negative.



    Given the problem statement, we'd expect something more like "if (i is a multiple of 3) or (i is a multiple of 5)", so:



    if ((i % 3 == 0) || (i % 5 == 0))


    Nitpicking:



    • If we don't need argc and argv, we can declare main as int main() with no arguments.

    • The return 0; at the end of main happens automatically in C++, so we don't have to write it ourselves.


    Note that there exists an arithmetic solution to the problem, which is much faster (it could even be done at compile-time in C++).




    We want to sum all the multiples of 3 or 5 less than 1000. We can think about the sequence of multiples of 3 as (3, 6, 9, 12, 15, ..., 999), which is the same as 3 * (1, 2, 3, 4, 5, ..., 333). [...]



    Such a sequence, where the difference between each number is constant, is called a finite arithmetic progression [and the sum is] a finite arithmetic series. The formula for the sum is 1/2 * n * (a_1 + a_n). where n is the number of terms being added, a_1 is the first element in the sequence, and a_n is the last element in the sequence.







    share|improve this answer









    $endgroup$








    • 3




      $begingroup$
      Even the brute-force formula could easily be done at compile-time, though it's slightly more unwieldy.
      $endgroup$
      – Deduplicator
      2 days ago






    • 1




      $begingroup$
      Is there a difference in speed by not adding argv and argc?
      $endgroup$
      – o2640110
      2 days ago











    • $begingroup$
      @o2640110 No there is not. :)
      $endgroup$
      – Rakete1111
      2 days ago






    • 1




      $begingroup$
      The arithmetic solution could be done at compile time, or even worked out on a 4-op calculator.
      $endgroup$
      – Laurent LA RIZZA
      yesterday














    21












    21








    21





    $begingroup$

    The code is basically fine.



    The if condition is perhaps a little complicated though. To interpret it you have to read "if not ((i is not a multiple of 3) and (i is not a multiple of 5))", which is a double negative.



    Given the problem statement, we'd expect something more like "if (i is a multiple of 3) or (i is a multiple of 5)", so:



    if ((i % 3 == 0) || (i % 5 == 0))


    Nitpicking:



    • If we don't need argc and argv, we can declare main as int main() with no arguments.

    • The return 0; at the end of main happens automatically in C++, so we don't have to write it ourselves.


    Note that there exists an arithmetic solution to the problem, which is much faster (it could even be done at compile-time in C++).




    We want to sum all the multiples of 3 or 5 less than 1000. We can think about the sequence of multiples of 3 as (3, 6, 9, 12, 15, ..., 999), which is the same as 3 * (1, 2, 3, 4, 5, ..., 333). [...]



    Such a sequence, where the difference between each number is constant, is called a finite arithmetic progression [and the sum is] a finite arithmetic series. The formula for the sum is 1/2 * n * (a_1 + a_n). where n is the number of terms being added, a_1 is the first element in the sequence, and a_n is the last element in the sequence.







    share|improve this answer









    $endgroup$



    The code is basically fine.



    The if condition is perhaps a little complicated though. To interpret it you have to read "if not ((i is not a multiple of 3) and (i is not a multiple of 5))", which is a double negative.



    Given the problem statement, we'd expect something more like "if (i is a multiple of 3) or (i is a multiple of 5)", so:



    if ((i % 3 == 0) || (i % 5 == 0))


    Nitpicking:



    • If we don't need argc and argv, we can declare main as int main() with no arguments.

    • The return 0; at the end of main happens automatically in C++, so we don't have to write it ourselves.


    Note that there exists an arithmetic solution to the problem, which is much faster (it could even be done at compile-time in C++).




    We want to sum all the multiples of 3 or 5 less than 1000. We can think about the sequence of multiples of 3 as (3, 6, 9, 12, 15, ..., 999), which is the same as 3 * (1, 2, 3, 4, 5, ..., 333). [...]



    Such a sequence, where the difference between each number is constant, is called a finite arithmetic progression [and the sum is] a finite arithmetic series. The formula for the sum is 1/2 * n * (a_1 + a_n). where n is the number of terms being added, a_1 is the first element in the sequence, and a_n is the last element in the sequence.








    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 2 days ago









    user673679user673679

    3,75311231




    3,75311231







    • 3




      $begingroup$
      Even the brute-force formula could easily be done at compile-time, though it's slightly more unwieldy.
      $endgroup$
      – Deduplicator
      2 days ago






    • 1




      $begingroup$
      Is there a difference in speed by not adding argv and argc?
      $endgroup$
      – o2640110
      2 days ago











    • $begingroup$
      @o2640110 No there is not. :)
      $endgroup$
      – Rakete1111
      2 days ago






    • 1




      $begingroup$
      The arithmetic solution could be done at compile time, or even worked out on a 4-op calculator.
      $endgroup$
      – Laurent LA RIZZA
      yesterday













    • 3




      $begingroup$
      Even the brute-force formula could easily be done at compile-time, though it's slightly more unwieldy.
      $endgroup$
      – Deduplicator
      2 days ago






    • 1




      $begingroup$
      Is there a difference in speed by not adding argv and argc?
      $endgroup$
      – o2640110
      2 days ago











    • $begingroup$
      @o2640110 No there is not. :)
      $endgroup$
      – Rakete1111
      2 days ago






    • 1




      $begingroup$
      The arithmetic solution could be done at compile time, or even worked out on a 4-op calculator.
      $endgroup$
      – Laurent LA RIZZA
      yesterday








    3




    3




    $begingroup$
    Even the brute-force formula could easily be done at compile-time, though it's slightly more unwieldy.
    $endgroup$
    – Deduplicator
    2 days ago




    $begingroup$
    Even the brute-force formula could easily be done at compile-time, though it's slightly more unwieldy.
    $endgroup$
    – Deduplicator
    2 days ago




    1




    1




    $begingroup$
    Is there a difference in speed by not adding argv and argc?
    $endgroup$
    – o2640110
    2 days ago





    $begingroup$
    Is there a difference in speed by not adding argv and argc?
    $endgroup$
    – o2640110
    2 days ago













    $begingroup$
    @o2640110 No there is not. :)
    $endgroup$
    – Rakete1111
    2 days ago




    $begingroup$
    @o2640110 No there is not. :)
    $endgroup$
    – Rakete1111
    2 days ago




    1




    1




    $begingroup$
    The arithmetic solution could be done at compile time, or even worked out on a 4-op calculator.
    $endgroup$
    – Laurent LA RIZZA
    yesterday





    $begingroup$
    The arithmetic solution could be done at compile time, or even worked out on a 4-op calculator.
    $endgroup$
    – Laurent LA RIZZA
    yesterday














    17












    $begingroup$

    Yes, there are ways to do this that avoid most of the divisions, and are probably faster as well.



    Let's start with a simplified version of the problem: add up all the multiples of 3.



    Now, you could do a simplified version of what you've written:



    int sum = 0;

    for (int i=1; i<1000; i++)
    if (i % 3 == 0)
    sum += i;


    ...but we know up front that 1 and 2 aren't multiples of three. We can generate all multiples of three by counting by 3's:



    int sum = 0;

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


    Obviously enough, we can do the same thing for multiples of 5:



    int sum = 0;

    for (int i=0; i<1000; i += 5)
    sum += i;


    But if we do both in succession:



    int sum = 0;

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

    for (int i=0; i<1000; i += 5)
    sum += i;


    ...we'll get the wrong answer. The problem now is that if a number is a multiple of both 3 and 5 (e.g., 15) we've counted it twice. There are a few ways we can avoid that. One is to have the second loop add i to the sum if and only if i is not a multiple of 3.



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


    Another is to initially add those, but then add a third loop that generates only the numbers that are multiples of both 3 and 5, and subtracts those from the overall result:



    int product = 3 * 5;

    for (int i = 0; i < 1000; i += product)
    sum -= i;


    Since you're (apparently) more interested in learning programming than in learning math, I'll only sketch out the next step. There are ways to avoid doing those loops at all though. What we're really doing is (for two different values of N) summing a series of 1N + 2N + 3N + 4N + ...



    Using the distributive property, we can turn that into N * (1 + 2 + 3 + 4 + ...). Gauss invented an easy way to sum a series like 1 + 2 + 3 + 4 + ..., so what we need to do is compute the number of terms of that series we need for each of 3 and 5, compute them, multiply by 3 and 5 respectively, and add together the results. Then do the same for multiples of 15, and subtract that from the result. The number of terms in each series we need will be the upper limit divided by the N for that series--so for multiples of 3, we have 1000/3 terms, and for multiples of 5 we have 1000/5 terms.



    So, we can compute the final value as:



    3 * gauss_sum(1000/3) + 5 * gauss_sum(1000/5) - 15 * gauss_sum(1000/15)


    ...and we're left with no loops at all, so we can compute the correct value for any upper limit (up to what fits in an unsigned long long, anyway) in constant time.






    share|improve this answer











    $endgroup$

















      17












      $begingroup$

      Yes, there are ways to do this that avoid most of the divisions, and are probably faster as well.



      Let's start with a simplified version of the problem: add up all the multiples of 3.



      Now, you could do a simplified version of what you've written:



      int sum = 0;

      for (int i=1; i<1000; i++)
      if (i % 3 == 0)
      sum += i;


      ...but we know up front that 1 and 2 aren't multiples of three. We can generate all multiples of three by counting by 3's:



      int sum = 0;

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


      Obviously enough, we can do the same thing for multiples of 5:



      int sum = 0;

      for (int i=0; i<1000; i += 5)
      sum += i;


      But if we do both in succession:



      int sum = 0;

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

      for (int i=0; i<1000; i += 5)
      sum += i;


      ...we'll get the wrong answer. The problem now is that if a number is a multiple of both 3 and 5 (e.g., 15) we've counted it twice. There are a few ways we can avoid that. One is to have the second loop add i to the sum if and only if i is not a multiple of 3.



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


      Another is to initially add those, but then add a third loop that generates only the numbers that are multiples of both 3 and 5, and subtracts those from the overall result:



      int product = 3 * 5;

      for (int i = 0; i < 1000; i += product)
      sum -= i;


      Since you're (apparently) more interested in learning programming than in learning math, I'll only sketch out the next step. There are ways to avoid doing those loops at all though. What we're really doing is (for two different values of N) summing a series of 1N + 2N + 3N + 4N + ...



      Using the distributive property, we can turn that into N * (1 + 2 + 3 + 4 + ...). Gauss invented an easy way to sum a series like 1 + 2 + 3 + 4 + ..., so what we need to do is compute the number of terms of that series we need for each of 3 and 5, compute them, multiply by 3 and 5 respectively, and add together the results. Then do the same for multiples of 15, and subtract that from the result. The number of terms in each series we need will be the upper limit divided by the N for that series--so for multiples of 3, we have 1000/3 terms, and for multiples of 5 we have 1000/5 terms.



      So, we can compute the final value as:



      3 * gauss_sum(1000/3) + 5 * gauss_sum(1000/5) - 15 * gauss_sum(1000/15)


      ...and we're left with no loops at all, so we can compute the correct value for any upper limit (up to what fits in an unsigned long long, anyway) in constant time.






      share|improve this answer











      $endgroup$















        17












        17








        17





        $begingroup$

        Yes, there are ways to do this that avoid most of the divisions, and are probably faster as well.



        Let's start with a simplified version of the problem: add up all the multiples of 3.



        Now, you could do a simplified version of what you've written:



        int sum = 0;

        for (int i=1; i<1000; i++)
        if (i % 3 == 0)
        sum += i;


        ...but we know up front that 1 and 2 aren't multiples of three. We can generate all multiples of three by counting by 3's:



        int sum = 0;

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


        Obviously enough, we can do the same thing for multiples of 5:



        int sum = 0;

        for (int i=0; i<1000; i += 5)
        sum += i;


        But if we do both in succession:



        int sum = 0;

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

        for (int i=0; i<1000; i += 5)
        sum += i;


        ...we'll get the wrong answer. The problem now is that if a number is a multiple of both 3 and 5 (e.g., 15) we've counted it twice. There are a few ways we can avoid that. One is to have the second loop add i to the sum if and only if i is not a multiple of 3.



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


        Another is to initially add those, but then add a third loop that generates only the numbers that are multiples of both 3 and 5, and subtracts those from the overall result:



        int product = 3 * 5;

        for (int i = 0; i < 1000; i += product)
        sum -= i;


        Since you're (apparently) more interested in learning programming than in learning math, I'll only sketch out the next step. There are ways to avoid doing those loops at all though. What we're really doing is (for two different values of N) summing a series of 1N + 2N + 3N + 4N + ...



        Using the distributive property, we can turn that into N * (1 + 2 + 3 + 4 + ...). Gauss invented an easy way to sum a series like 1 + 2 + 3 + 4 + ..., so what we need to do is compute the number of terms of that series we need for each of 3 and 5, compute them, multiply by 3 and 5 respectively, and add together the results. Then do the same for multiples of 15, and subtract that from the result. The number of terms in each series we need will be the upper limit divided by the N for that series--so for multiples of 3, we have 1000/3 terms, and for multiples of 5 we have 1000/5 terms.



        So, we can compute the final value as:



        3 * gauss_sum(1000/3) + 5 * gauss_sum(1000/5) - 15 * gauss_sum(1000/15)


        ...and we're left with no loops at all, so we can compute the correct value for any upper limit (up to what fits in an unsigned long long, anyway) in constant time.






        share|improve this answer











        $endgroup$



        Yes, there are ways to do this that avoid most of the divisions, and are probably faster as well.



        Let's start with a simplified version of the problem: add up all the multiples of 3.



        Now, you could do a simplified version of what you've written:



        int sum = 0;

        for (int i=1; i<1000; i++)
        if (i % 3 == 0)
        sum += i;


        ...but we know up front that 1 and 2 aren't multiples of three. We can generate all multiples of three by counting by 3's:



        int sum = 0;

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


        Obviously enough, we can do the same thing for multiples of 5:



        int sum = 0;

        for (int i=0; i<1000; i += 5)
        sum += i;


        But if we do both in succession:



        int sum = 0;

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

        for (int i=0; i<1000; i += 5)
        sum += i;


        ...we'll get the wrong answer. The problem now is that if a number is a multiple of both 3 and 5 (e.g., 15) we've counted it twice. There are a few ways we can avoid that. One is to have the second loop add i to the sum if and only if i is not a multiple of 3.



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


        Another is to initially add those, but then add a third loop that generates only the numbers that are multiples of both 3 and 5, and subtracts those from the overall result:



        int product = 3 * 5;

        for (int i = 0; i < 1000; i += product)
        sum -= i;


        Since you're (apparently) more interested in learning programming than in learning math, I'll only sketch out the next step. There are ways to avoid doing those loops at all though. What we're really doing is (for two different values of N) summing a series of 1N + 2N + 3N + 4N + ...



        Using the distributive property, we can turn that into N * (1 + 2 + 3 + 4 + ...). Gauss invented an easy way to sum a series like 1 + 2 + 3 + 4 + ..., so what we need to do is compute the number of terms of that series we need for each of 3 and 5, compute them, multiply by 3 and 5 respectively, and add together the results. Then do the same for multiples of 15, and subtract that from the result. The number of terms in each series we need will be the upper limit divided by the N for that series--so for multiples of 3, we have 1000/3 terms, and for multiples of 5 we have 1000/5 terms.



        So, we can compute the final value as:



        3 * gauss_sum(1000/3) + 5 * gauss_sum(1000/5) - 15 * gauss_sum(1000/15)


        ...and we're left with no loops at all, so we can compute the correct value for any upper limit (up to what fits in an unsigned long long, anyway) in constant time.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 2 days ago

























        answered 2 days ago









        Jerry CoffinJerry Coffin

        28.7k462130




        28.7k462130





















            11












            $begingroup$

            The one bit that is absolutely not fine is this line:



            if (!(i % 3 && i % 5))


            It is clever, and clever is bad. The question was about "all integers that are multiples of 3 or 5." So write that:



            if (i % 3 == 0 || i % 5 == 0)





            share|improve this answer









            $endgroup$








            • 1




              $begingroup$
              +1! Any time you write code that has to be deciphered, you should change it to something that can be read. To be honest, half the time, I'd take it a step further, and actually put i%3 into a variable: divisibleBy3. That way, the IF statement is simply if (divisbleBy3 || divisibleBy5) - doesn't get much more readable than that.
              $endgroup$
              – Kevin
              yesterday






            • 2




              $begingroup$
              @Kevin: Another possibility would be to define a lambda like: auto divisibleBy = [](int x, int y) return x % y == 0; ; Then you'd just use: if (divisibleBy(i, 3) || divisibleBy(i, 5)) ...
              $endgroup$
              – Jerry Coffin
              yesterday










            • $begingroup$
              Just to add to this, you can see the compiler output here. godbolt.org/z/lAws-Z At least for this compiler (clang 7, fully optimised) the two versions compile to exactly the same thing. That all to say, it's OK to use the readable version over what you expect is more efficient: the compiler knows better than almost any human programmer what will be efficient.
              $endgroup$
              – Josiah
              16 hours ago















            11












            $begingroup$

            The one bit that is absolutely not fine is this line:



            if (!(i % 3 && i % 5))


            It is clever, and clever is bad. The question was about "all integers that are multiples of 3 or 5." So write that:



            if (i % 3 == 0 || i % 5 == 0)





            share|improve this answer









            $endgroup$








            • 1




              $begingroup$
              +1! Any time you write code that has to be deciphered, you should change it to something that can be read. To be honest, half the time, I'd take it a step further, and actually put i%3 into a variable: divisibleBy3. That way, the IF statement is simply if (divisbleBy3 || divisibleBy5) - doesn't get much more readable than that.
              $endgroup$
              – Kevin
              yesterday






            • 2




              $begingroup$
              @Kevin: Another possibility would be to define a lambda like: auto divisibleBy = [](int x, int y) return x % y == 0; ; Then you'd just use: if (divisibleBy(i, 3) || divisibleBy(i, 5)) ...
              $endgroup$
              – Jerry Coffin
              yesterday










            • $begingroup$
              Just to add to this, you can see the compiler output here. godbolt.org/z/lAws-Z At least for this compiler (clang 7, fully optimised) the two versions compile to exactly the same thing. That all to say, it's OK to use the readable version over what you expect is more efficient: the compiler knows better than almost any human programmer what will be efficient.
              $endgroup$
              – Josiah
              16 hours ago













            11












            11








            11





            $begingroup$

            The one bit that is absolutely not fine is this line:



            if (!(i % 3 && i % 5))


            It is clever, and clever is bad. The question was about "all integers that are multiples of 3 or 5." So write that:



            if (i % 3 == 0 || i % 5 == 0)





            share|improve this answer









            $endgroup$



            The one bit that is absolutely not fine is this line:



            if (!(i % 3 && i % 5))


            It is clever, and clever is bad. The question was about "all integers that are multiples of 3 or 5." So write that:



            if (i % 3 == 0 || i % 5 == 0)






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 2 days ago









            gnasher729gnasher729

            2,252813




            2,252813







            • 1




              $begingroup$
              +1! Any time you write code that has to be deciphered, you should change it to something that can be read. To be honest, half the time, I'd take it a step further, and actually put i%3 into a variable: divisibleBy3. That way, the IF statement is simply if (divisbleBy3 || divisibleBy5) - doesn't get much more readable than that.
              $endgroup$
              – Kevin
              yesterday






            • 2




              $begingroup$
              @Kevin: Another possibility would be to define a lambda like: auto divisibleBy = [](int x, int y) return x % y == 0; ; Then you'd just use: if (divisibleBy(i, 3) || divisibleBy(i, 5)) ...
              $endgroup$
              – Jerry Coffin
              yesterday










            • $begingroup$
              Just to add to this, you can see the compiler output here. godbolt.org/z/lAws-Z At least for this compiler (clang 7, fully optimised) the two versions compile to exactly the same thing. That all to say, it's OK to use the readable version over what you expect is more efficient: the compiler knows better than almost any human programmer what will be efficient.
              $endgroup$
              – Josiah
              16 hours ago












            • 1




              $begingroup$
              +1! Any time you write code that has to be deciphered, you should change it to something that can be read. To be honest, half the time, I'd take it a step further, and actually put i%3 into a variable: divisibleBy3. That way, the IF statement is simply if (divisbleBy3 || divisibleBy5) - doesn't get much more readable than that.
              $endgroup$
              – Kevin
              yesterday






            • 2




              $begingroup$
              @Kevin: Another possibility would be to define a lambda like: auto divisibleBy = [](int x, int y) return x % y == 0; ; Then you'd just use: if (divisibleBy(i, 3) || divisibleBy(i, 5)) ...
              $endgroup$
              – Jerry Coffin
              yesterday










            • $begingroup$
              Just to add to this, you can see the compiler output here. godbolt.org/z/lAws-Z At least for this compiler (clang 7, fully optimised) the two versions compile to exactly the same thing. That all to say, it's OK to use the readable version over what you expect is more efficient: the compiler knows better than almost any human programmer what will be efficient.
              $endgroup$
              – Josiah
              16 hours ago







            1




            1




            $begingroup$
            +1! Any time you write code that has to be deciphered, you should change it to something that can be read. To be honest, half the time, I'd take it a step further, and actually put i%3 into a variable: divisibleBy3. That way, the IF statement is simply if (divisbleBy3 || divisibleBy5) - doesn't get much more readable than that.
            $endgroup$
            – Kevin
            yesterday




            $begingroup$
            +1! Any time you write code that has to be deciphered, you should change it to something that can be read. To be honest, half the time, I'd take it a step further, and actually put i%3 into a variable: divisibleBy3. That way, the IF statement is simply if (divisbleBy3 || divisibleBy5) - doesn't get much more readable than that.
            $endgroup$
            – Kevin
            yesterday




            2




            2




            $begingroup$
            @Kevin: Another possibility would be to define a lambda like: auto divisibleBy = [](int x, int y) return x % y == 0; ; Then you'd just use: if (divisibleBy(i, 3) || divisibleBy(i, 5)) ...
            $endgroup$
            – Jerry Coffin
            yesterday




            $begingroup$
            @Kevin: Another possibility would be to define a lambda like: auto divisibleBy = [](int x, int y) return x % y == 0; ; Then you'd just use: if (divisibleBy(i, 3) || divisibleBy(i, 5)) ...
            $endgroup$
            – Jerry Coffin
            yesterday












            $begingroup$
            Just to add to this, you can see the compiler output here. godbolt.org/z/lAws-Z At least for this compiler (clang 7, fully optimised) the two versions compile to exactly the same thing. That all to say, it's OK to use the readable version over what you expect is more efficient: the compiler knows better than almost any human programmer what will be efficient.
            $endgroup$
            – Josiah
            16 hours ago




            $begingroup$
            Just to add to this, you can see the compiler output here. godbolt.org/z/lAws-Z At least for this compiler (clang 7, fully optimised) the two versions compile to exactly the same thing. That all to say, it's OK to use the readable version over what you expect is more efficient: the compiler knows better than almost any human programmer what will be efficient.
            $endgroup$
            – Josiah
            16 hours ago











            0












            $begingroup$

            As you were asking for "less division"... Here's a different approach with absolutely no division, multiplication or modulo operations. We have two counters t (for increment three) and f (for increment five), and update them in a single while loop. Due to the increments it's guaranteed t and f will always be numbers divisible by 3 resp. 5. Now we just have to pick which counter to update (the lower one), and to handle the case when both counters occasionally meet :)



            (You can avoid the std::min-line and put the addition to result into the if/else if/else-part, but with this it's easier to understand what happens.)



            #include <iostream>

            int main()
            unsigned t=0, f=0;
            unsigned result=0;
            while (t<1000)
            result+=std::min(t, f);

            if (t<f) t+=3;
            else if (f<t) f+=5;
            else // f==t
            t+=3;
            f+=5;


            std::cout << "Result: " << result << std::endl;
            return(0);






            share|improve this answer









            $endgroup$












            • $begingroup$
              You know that return is not a function? That can be crucial in C++ when the return-type is deduced with decltype(auto).
              $endgroup$
              – Deduplicator
              6 hours ago










            • $begingroup$
              Yes I know that. @Deduplicator, do you have an example where brackets actually do change the return type?
              $endgroup$
              – jvb
              6 hours ago










            • $begingroup$
              As I said, additional parentheses around the return-expression are meaningful when the return-type is deduced with decltype(auto).
              $endgroup$
              – Deduplicator
              4 hours ago










            • $begingroup$
              Ok, so the deduced function types indeed would be T() vs T&() in your example - actually different in regards to std::type_info, but only in this aspect - and neither deduced type is technically incorrect or leads to erroneous behaviour. As a consequence, I wouldn't encourage comparing type info obtained with auto :)
              $endgroup$
              – jvb
              1 hour ago










            • $begingroup$
              std::type_info (returned by typeid) only knows fully decayed types. And if i was not a global, but e.g. a local or parameter, the difference between a copy and a reference may be more relevant.
              $endgroup$
              – Deduplicator
              50 mins ago
















            0












            $begingroup$

            As you were asking for "less division"... Here's a different approach with absolutely no division, multiplication or modulo operations. We have two counters t (for increment three) and f (for increment five), and update them in a single while loop. Due to the increments it's guaranteed t and f will always be numbers divisible by 3 resp. 5. Now we just have to pick which counter to update (the lower one), and to handle the case when both counters occasionally meet :)



            (You can avoid the std::min-line and put the addition to result into the if/else if/else-part, but with this it's easier to understand what happens.)



            #include <iostream>

            int main()
            unsigned t=0, f=0;
            unsigned result=0;
            while (t<1000)
            result+=std::min(t, f);

            if (t<f) t+=3;
            else if (f<t) f+=5;
            else // f==t
            t+=3;
            f+=5;


            std::cout << "Result: " << result << std::endl;
            return(0);






            share|improve this answer









            $endgroup$












            • $begingroup$
              You know that return is not a function? That can be crucial in C++ when the return-type is deduced with decltype(auto).
              $endgroup$
              – Deduplicator
              6 hours ago










            • $begingroup$
              Yes I know that. @Deduplicator, do you have an example where brackets actually do change the return type?
              $endgroup$
              – jvb
              6 hours ago










            • $begingroup$
              As I said, additional parentheses around the return-expression are meaningful when the return-type is deduced with decltype(auto).
              $endgroup$
              – Deduplicator
              4 hours ago










            • $begingroup$
              Ok, so the deduced function types indeed would be T() vs T&() in your example - actually different in regards to std::type_info, but only in this aspect - and neither deduced type is technically incorrect or leads to erroneous behaviour. As a consequence, I wouldn't encourage comparing type info obtained with auto :)
              $endgroup$
              – jvb
              1 hour ago










            • $begingroup$
              std::type_info (returned by typeid) only knows fully decayed types. And if i was not a global, but e.g. a local or parameter, the difference between a copy and a reference may be more relevant.
              $endgroup$
              – Deduplicator
              50 mins ago














            0












            0








            0





            $begingroup$

            As you were asking for "less division"... Here's a different approach with absolutely no division, multiplication or modulo operations. We have two counters t (for increment three) and f (for increment five), and update them in a single while loop. Due to the increments it's guaranteed t and f will always be numbers divisible by 3 resp. 5. Now we just have to pick which counter to update (the lower one), and to handle the case when both counters occasionally meet :)



            (You can avoid the std::min-line and put the addition to result into the if/else if/else-part, but with this it's easier to understand what happens.)



            #include <iostream>

            int main()
            unsigned t=0, f=0;
            unsigned result=0;
            while (t<1000)
            result+=std::min(t, f);

            if (t<f) t+=3;
            else if (f<t) f+=5;
            else // f==t
            t+=3;
            f+=5;


            std::cout << "Result: " << result << std::endl;
            return(0);






            share|improve this answer









            $endgroup$



            As you were asking for "less division"... Here's a different approach with absolutely no division, multiplication or modulo operations. We have two counters t (for increment three) and f (for increment five), and update them in a single while loop. Due to the increments it's guaranteed t and f will always be numbers divisible by 3 resp. 5. Now we just have to pick which counter to update (the lower one), and to handle the case when both counters occasionally meet :)



            (You can avoid the std::min-line and put the addition to result into the if/else if/else-part, but with this it's easier to understand what happens.)



            #include <iostream>

            int main()
            unsigned t=0, f=0;
            unsigned result=0;
            while (t<1000)
            result+=std::min(t, f);

            if (t<f) t+=3;
            else if (f<t) f+=5;
            else // f==t
            t+=3;
            f+=5;


            std::cout << "Result: " << result << std::endl;
            return(0);







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 6 hours ago









            jvbjvb

            899210




            899210











            • $begingroup$
              You know that return is not a function? That can be crucial in C++ when the return-type is deduced with decltype(auto).
              $endgroup$
              – Deduplicator
              6 hours ago










            • $begingroup$
              Yes I know that. @Deduplicator, do you have an example where brackets actually do change the return type?
              $endgroup$
              – jvb
              6 hours ago










            • $begingroup$
              As I said, additional parentheses around the return-expression are meaningful when the return-type is deduced with decltype(auto).
              $endgroup$
              – Deduplicator
              4 hours ago










            • $begingroup$
              Ok, so the deduced function types indeed would be T() vs T&() in your example - actually different in regards to std::type_info, but only in this aspect - and neither deduced type is technically incorrect or leads to erroneous behaviour. As a consequence, I wouldn't encourage comparing type info obtained with auto :)
              $endgroup$
              – jvb
              1 hour ago










            • $begingroup$
              std::type_info (returned by typeid) only knows fully decayed types. And if i was not a global, but e.g. a local or parameter, the difference between a copy and a reference may be more relevant.
              $endgroup$
              – Deduplicator
              50 mins ago

















            • $begingroup$
              You know that return is not a function? That can be crucial in C++ when the return-type is deduced with decltype(auto).
              $endgroup$
              – Deduplicator
              6 hours ago










            • $begingroup$
              Yes I know that. @Deduplicator, do you have an example where brackets actually do change the return type?
              $endgroup$
              – jvb
              6 hours ago










            • $begingroup$
              As I said, additional parentheses around the return-expression are meaningful when the return-type is deduced with decltype(auto).
              $endgroup$
              – Deduplicator
              4 hours ago










            • $begingroup$
              Ok, so the deduced function types indeed would be T() vs T&() in your example - actually different in regards to std::type_info, but only in this aspect - and neither deduced type is technically incorrect or leads to erroneous behaviour. As a consequence, I wouldn't encourage comparing type info obtained with auto :)
              $endgroup$
              – jvb
              1 hour ago










            • $begingroup$
              std::type_info (returned by typeid) only knows fully decayed types. And if i was not a global, but e.g. a local or parameter, the difference between a copy and a reference may be more relevant.
              $endgroup$
              – Deduplicator
              50 mins ago
















            $begingroup$
            You know that return is not a function? That can be crucial in C++ when the return-type is deduced with decltype(auto).
            $endgroup$
            – Deduplicator
            6 hours ago




            $begingroup$
            You know that return is not a function? That can be crucial in C++ when the return-type is deduced with decltype(auto).
            $endgroup$
            – Deduplicator
            6 hours ago












            $begingroup$
            Yes I know that. @Deduplicator, do you have an example where brackets actually do change the return type?
            $endgroup$
            – jvb
            6 hours ago




            $begingroup$
            Yes I know that. @Deduplicator, do you have an example where brackets actually do change the return type?
            $endgroup$
            – jvb
            6 hours ago












            $begingroup$
            As I said, additional parentheses around the return-expression are meaningful when the return-type is deduced with decltype(auto).
            $endgroup$
            – Deduplicator
            4 hours ago




            $begingroup$
            As I said, additional parentheses around the return-expression are meaningful when the return-type is deduced with decltype(auto).
            $endgroup$
            – Deduplicator
            4 hours ago












            $begingroup$
            Ok, so the deduced function types indeed would be T() vs T&() in your example - actually different in regards to std::type_info, but only in this aspect - and neither deduced type is technically incorrect or leads to erroneous behaviour. As a consequence, I wouldn't encourage comparing type info obtained with auto :)
            $endgroup$
            – jvb
            1 hour ago




            $begingroup$
            Ok, so the deduced function types indeed would be T() vs T&() in your example - actually different in regards to std::type_info, but only in this aspect - and neither deduced type is technically incorrect or leads to erroneous behaviour. As a consequence, I wouldn't encourage comparing type info obtained with auto :)
            $endgroup$
            – jvb
            1 hour ago












            $begingroup$
            std::type_info (returned by typeid) only knows fully decayed types. And if i was not a global, but e.g. a local or parameter, the difference between a copy and a reference may be more relevant.
            $endgroup$
            – Deduplicator
            50 mins ago





            $begingroup$
            std::type_info (returned by typeid) only knows fully decayed types. And if i was not a global, but e.g. a local or parameter, the difference between a copy and a reference may be more relevant.
            $endgroup$
            – Deduplicator
            50 mins ago











            o2640110 is a new contributor. Be nice, and check out our Code of Conduct.









            draft saved

            draft discarded


















            o2640110 is a new contributor. Be nice, and check out our Code of Conduct.












            o2640110 is a new contributor. Be nice, and check out our Code of Conduct.











            o2640110 is a new contributor. Be nice, and check out our Code of Conduct.














            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217660%2fproject-euler-1-in-c%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Благоевград Съдържание География | История | Население | Политика | Икономика и инфрастуктура | Здравеопазване | Образование и наука | Култура и забавления | Забележителности | Личности | Литература | Външни препратки | Бележки | Навигация42°01′18.99″ с. ш. 23°05′51″ и. д. / 42.021944° с. ш. 23.0975° и. д.*БлагоевградразширитередактиранеОфициален уебсайт на община БлагоевградНовинарски портал на Благоевград – blagoevgrad.euСайтове за БлагоевградНационален статистически институтdariknews.bgГригоровичъ, Викторъ. „Очеркъ путешествія по Европейской Турціи“. Москва, 1877.Стрезов, Георги. Два санджака от Източна Македония. Периодично списание на Българското книжовно дружество в Средец, кн. XXXVII и XXXVIII, 1891, стр. 18 – 19.Македония. Етнография и статистикаГаджанов, Димитър Г. Мюсюлманското население в Новоосвободените земи, в: Научна експедиция в Македония и Поморавието 1916, Военноиздателски комплекс „Св. Георги Победоносец“, Университетско издателство „Св. Климент Охридски“, София, 1993, стр. 244.паметник на незнайния четник&cd=18&hl=en&ct=clnk&client=firefox-a „История на днешен Благоевград“, взето от www.museumblg.com на 16 март 2010 г.„Справка за населението на град Благоевград, община Благоевград, област Благоевград, НСИ“„The population of all towns and villages in Blagoevgrad Province with 50 inhabitants or more according to census results and latest official estimates“„Ethnic composition, all places: 2011 census“История на Неврокопска епархия.Национален статистически институтМюсюлманско изповедание. Главно мюфтийствоНационален публичен регистър на храмовете в БългарияМюсюлманско изповедание. Главно мюфтийствоwww.dnes.bg Джамията в Благоевград не била паленаwww.sesc-bg.orgСписък на побратимени градовеТехническо побратимяванеГУМ грейва в цветовете на нощен Лас Вегас под името „Largo“, „МОЛ Благоевград“..., в. „Струма“grabo.bgwww.cinemaxbg.comррр4238731-067cad53a-0546-417b-a3d3-51e49b1d2232147736077147736077

            What is the best defense strategy for Survival in Grand Theft Auto Online?What is JP used for in Grand Theft Auto Online?How do I setup a Crew HQ in Grand Theft Auto Online?How does stealth work in Grand Theft Auto Online?Is it possible to own more than 10 cars in Grand Theft Auto online?Where to find truck/trailers in Grand Theft Auto OnlineWhat are some of the best missions to do on Grand Theft Auto 5 onlineFastest Car in Grand Theft Auto V PCHow to setup a Crew vs Crew online session in Grand Theft Auto Online?Grand theft auto 5 crossplayingRestart Grand Theft Auto V Online?

            How does Billy Russo acquire his 'Jigsaw' mask? Unicorn Meta Zoo #1: Why another podcast? Announcing the arrival of Valued Associate #679: Cesar Manara Favourite questions and answers from the 1st quarter of 2019Why does Bane wear the mask?Why does Kylo Ren wear a mask?Why did Captain America remove his mask while fighting Batroc the Leaper?How did the OA acquire her wisdom?Is Billy Breckenridge gay?How does Adrian Toomes hide his earnings from the IRS?What is the state of affairs on Nootka Sound by the end of season 1?How did Tia Dalma acquire Captain Barbossa's body?How is one “Deemed Worthy”, to acquire the Greatsword “Dawn”?How did Karen acquire the handgun?