Reputation: 1
I'm pretty new to this whole PHP business, and trying to do the first challenge at ProjectEuler.com. Simple question: What numbers below 1000 are divisible by 3 and/or 5? Add those numbers together.
Because my code started to spew out incredible long strings of numbers, I just stuck to 20 for now.
This is the code I'm using:
<?php
for ($test = 1; $test <= 20; $test++) {
$total = 0;
if (($test % 3 == 0) && ($test % 5 == 0)) {
$total += $test;
}
elseif ($test % 3 == 0) {
$total += $test;
}
elseif ($test % 5 == 0) {
$total += $test;
}
}
echo $total;
?>
I feel this is a pretty logical approach to the situation, although it doesn't seem to work. What am I doing wrong here?
Kind regards, Sander
/E: Thanks to everyone helping out!
Upvotes: 0
Views: 692
Reputation: 862
The simplest solution is:
text below is quoted
Rather than using range/loop based solutions you may wish to leverage more math than brute force.
There is a simple way to get the sum of multiples of a number, less than a number.
For instance, the sum of multiples of 3 up to 1000 are: 3 + 6 + 9 + ... + 999 Which can be rewritten as: 3* ( 1 + 2 + 3 + ... + 333)
There is a simple way to sum up all numbers 1-N:
Sum(1,N) = N*(N+1)/2
So a sample function would be
function unitSum($n) {
return ($n*($n+1))/2;
}
So now getting all multiples of 3 less than 1000 (aka up to and including 999) has been reduced to:
3*unitSum((int)(999/3))
You can do the same for multiples of 5:
5*unitSum((int)(999/5))
But there is a caveat! Both of these count multiples of both such as 15, 30, etc It counts them twice, one for each. So in order to balance that out, you subtract once.
15*unitSum((int)(999/15))
So in total, the equation is:
$sum = 3*unitSum((int)(999/3)) + 5*unitSum((int)(999/5)) - 15*unitSum((int)(999/15))
So now rather than looping over a large set of numbers, and doing comparisons, you are just doing some simple multiplication!
Upvotes: 0
Reputation: 20737
If you are interested in validating your code after it runs then I suggest this for ease-of-use:
$to_be_summed = array();
for($i = 1; $i <= 1000; ++$i)
{
if($i%3 === 0 && $i%5 === 0)
{
$to_be_summed[] = $i;
}
}
echo array_sum($to_be_summed);
echo '<br><br>';
// See which numbers met the criteria
echo '<pre>'.print_r($to_be_summed, true).'</pre>';
Upvotes: 0
Reputation: 41810
Don't initialize $total
inside your loop. Otherwise it resets to 0
with every iteration, so after the loop it will only equal whatever the last number was, or zero if the last number wasn't divisible by three or five.
You don't need that many conditions. You can just use an or (||
) with one if
.
$total = 0;
for ($test = 1; $test <= 20; $test++) {
if (($test % 3 == 0) || ($test % 5 == 0)) {
$total += $test;
}
}
echo $total;
Upvotes: 3
Reputation: 2708
You want to add $test
to $total
, so you can either do:
$total = $total + $test;
or $total += $test;
, but not both!
You are also resetting $total
each time you reset the loop, so you will want $total = 0;
to be outside of your for-loop.
Give this a try:
<?php
$total = 0;
for ($test = 1; $test <= 20; $test++) {
if (($test % 3 == 0) && ($test % 5 == 0)) {
$total += $test;
}
elseif ($test % 3 == 0) {
$total += $test;
}
elseif ($test % 5 == 0) {
$total += $test;
}
}
echo $total;
?>
Upvotes: 1