user961885
user961885

Reputation: 89

Make pattern of asterisks and zeros in increasing lengths

I'm trying to echo stars and zero like the pattern below

*
***0
******00
**********000

The length of the asterisks grows by an increasing factor (in a ballooning fashion) -- the previous number of asterisks plus the current iteration number.

The length of the zeros increases by a static factor.

My code currently looks like this:

for ($i=0; $i<=10; $i++)
{   
    echo "*";
    for ($j=0; $j<$i; $j++)
    {   
       echo "*";
    }
    for ($z=0; $z<$i; $z++)
    {
        echo "0";
    }       
    echo "</br>";    
} 

However I'm getting this result:

*
**0
***00
****000
*****0000
******00000

Upvotes: 2

Views: 15363

Answers (5)

mickmackusa
mickmackusa

Reputation: 48011

I quite like @jordandoyle's approach, but I correct the zeros pattern by subtracting 1 from $i in the second str_replace()..

Code: (Demo)

$number = 5;
for ($i = 1; $i <= $number; ++$i) {
    echo str_repeat('*', $i * .5 * ($i + 1))
         . str_repeat('0', $i - 1)
         . PHP_EOL;
}

Output:

*
***0
******00
**********000
***************0000

If this answer lacks significant uniqueness versus an earlier answer, I'll include a recursive approach as well (instead of a classic loop).

Code: (Demo)

function printLines($i, $lines = [], $newline = PHP_EOL) {
    if ($i > 0) {
        array_unshift(
            $lines,
            str_repeat('*', $i * .5 * ($i + 1))
                . str_repeat('0', $i - 1)
        );
        printLines(--$i, $lines);
    } else {
        echo implode($newline, $lines);
    }
}

printLines(5);

You can even copy the previous line and insert it into the middle of the next line to form the desired pattern. This is the functional-style equivalent of @CoertMetz's nested loop technique.

Code: (Demo)

$number = 5;
$line = '';
for ($i = 1; $i <= $number; ++$i) {
    echo (
             $line = str_repeat('*', $i)
                 . $line
                 . ($i > 1 ? '0' : '')
         )
         . PHP_EOL;
}

All above techniques deliver the same result.

Upvotes: 0

Jordan Doyle
Jordan Doyle

Reputation: 3026

Here's what I got:

for($i = 1; $i != 5; $i++)
{
    $triangle = (0.5 * $i) * ($i + 1);
    echo str_repeat('*', $triangle) . str_repeat('0', $i) . PHP_EOL;
}

Uses the formula 0.5n(n + 1) - the triangle numbers formula.

Example output:

*0
***00
******000
**********0000

Upvotes: 0

Green Black
Green Black

Reputation: 5084

Smells like homework... But ok, what about this:

$star = "*";

echo $star."\n";

    for ($i=0; $i<=10; $i++)
    {   
        $star = $star."**";
        echo $star;

        echo str_repeat("0", $i+1);

        echo "\n";    
    } 

Outcome:

*
***0
*****00
*******000
*********0000
***********00000
*************000000
***************0000000
*****************00000000
*******************000000000
*********************0000000000
***********************00000000000

Demo:

http://sandbox.onlinephpfunctions.com/code/583644f782005adb9e018b965cbbdefaf63c7c79

Upvotes: -1

Coert Metz
Coert Metz

Reputation: 902

I think something like this is more efficient; you can cache the current sequence of stars and zeros.

$cache_star = "";
$cache_zero = "";
for ($i=1; $i<=10; $i++)
{
    for ($j=1; $j<=$i; $j++)
    {   
       $cache_star .= "*";
    }
    echo $cache_star.$cache_zero;
    $cache_zero .= "0";
}

Upvotes: 1

mellamokb
mellamokb

Reputation: 56779

The number of stars is indicated by triangle numbers, 1, 1+2, 1+2+3. You want to increment your inner loop max value by $i with every iteration:

$k = 0;
for ($i=1; $i<=10; $i++)
{
    $k += $i;
    for ($j=1; $j<=$k; $j++)
    {   
       echo "*";
    }
    ...
}

This is also a good case where your loops should be initialized with 1 rather than 0, because it is more intuitive. 0-based loops work best when you are working with arrays.

Upvotes: 6

Related Questions