Sander
Sander

Reputation: 1

Add every number below 20 divisible by 3 and 5

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

Answers (6)

Wizard
Wizard

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

MonkeyZeus
MonkeyZeus

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

Don&#39;t Panic
Don&#39;t Panic

Reputation: 41810

  1. 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.

  2. 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

Yaman Jain
Yaman Jain

Reputation: 1251

Initialize $total variable before entering for loop.

Upvotes: 0

Felix Guo
Felix Guo

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

Rick de Gier
Rick de Gier

Reputation: 62

Remove = from += your I think adding twice.

Upvotes: -1

Related Questions