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;
$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;
c++ beginner programming-challenge
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$
add a comment |
$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;
c++ beginner programming-challenge
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 ofnbut 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
add a comment |
$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;
c++ beginner programming-challenge
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
c++ beginner programming-challenge
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.
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 ofnbut 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
add a comment |
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 ofnbut 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
add a comment |
4 Answers
4
active
oldest
votes
$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
argcandargv, we can declare main asint 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 as3 * (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.
$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 addingargvandargc?
$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
add a comment |
$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.
$endgroup$
add a comment |
$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)
$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
add a comment |
$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);
$endgroup$
$begingroup$
You know thatreturnis not a function? That can be crucial in C++ when the return-type is deduced withdecltype(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 withdecltype(auto).
$endgroup$
– Deduplicator
4 hours ago
$begingroup$
Ok, so the deduced function types indeed would beT()vsT&()in your example - actually different in regards tostd::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 withauto:)
$endgroup$
– jvb
1 hour ago
$begingroup$
std::type_info(returned bytypeid) only knows fully decayed types. And ifiwas 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
$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
argcandargv, we can declare main asint 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 as3 * (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.
$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 addingargvandargc?
$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
add a comment |
$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
argcandargv, we can declare main asint 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 as3 * (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.
$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 addingargvandargc?
$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
add a comment |
$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
argcandargv, we can declare main asint 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 as3 * (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.
$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
argcandargv, we can declare main asint 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 as3 * (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.
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 addingargvandargc?
$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
add a comment |
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 addingargvandargc?
$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
add a comment |
$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.
$endgroup$
add a comment |
$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.
$endgroup$
add a comment |
$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.
$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.
edited 2 days ago
answered 2 days ago
Jerry CoffinJerry Coffin
28.7k462130
28.7k462130
add a comment |
add a comment |
$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)
$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
add a comment |
$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)
$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
add a comment |
$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)
$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)
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
add a comment |
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
add a comment |
$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);
$endgroup$
$begingroup$
You know thatreturnis not a function? That can be crucial in C++ when the return-type is deduced withdecltype(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 withdecltype(auto).
$endgroup$
– Deduplicator
4 hours ago
$begingroup$
Ok, so the deduced function types indeed would beT()vsT&()in your example - actually different in regards tostd::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 withauto:)
$endgroup$
– jvb
1 hour ago
$begingroup$
std::type_info(returned bytypeid) only knows fully decayed types. And ifiwas 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
add a comment |
$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);
$endgroup$
$begingroup$
You know thatreturnis not a function? That can be crucial in C++ when the return-type is deduced withdecltype(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 withdecltype(auto).
$endgroup$
– Deduplicator
4 hours ago
$begingroup$
Ok, so the deduced function types indeed would beT()vsT&()in your example - actually different in regards tostd::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 withauto:)
$endgroup$
– jvb
1 hour ago
$begingroup$
std::type_info(returned bytypeid) only knows fully decayed types. And ifiwas 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
add a comment |
$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);
$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);
answered 6 hours ago
jvbjvb
899210
899210
$begingroup$
You know thatreturnis not a function? That can be crucial in C++ when the return-type is deduced withdecltype(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 withdecltype(auto).
$endgroup$
– Deduplicator
4 hours ago
$begingroup$
Ok, so the deduced function types indeed would beT()vsT&()in your example - actually different in regards tostd::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 withauto:)
$endgroup$
– jvb
1 hour ago
$begingroup$
std::type_info(returned bytypeid) only knows fully decayed types. And ifiwas 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
add a comment |
$begingroup$
You know thatreturnis not a function? That can be crucial in C++ when the return-type is deduced withdecltype(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 withdecltype(auto).
$endgroup$
– Deduplicator
4 hours ago
$begingroup$
Ok, so the deduced function types indeed would beT()vsT&()in your example - actually different in regards tostd::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 withauto:)
$endgroup$
– jvb
1 hour ago
$begingroup$
std::type_info(returned bytypeid) only knows fully decayed types. And ifiwas 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
add a comment |
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.
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
nbut 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