'How to do nested loop in descending order?

What I want to get with for loop. Something will be like this.

*
**
***
****
*****
****
***
**
*

This thing I want to create right now I have this code.

<?php
    
    $i = 1;
    $end = 5;
    $star = "*";
    
    for($i; $i <= $end; $i++){
        for($b=1; $b <= $i; $b++){
            echo $star;
        }
            
            
        if($i == $end){
            for($c=1; $c <= $end; $c++ ){
                for($d=i; $d >= 2; $d--){
                    echo $star;
                }
                echo "<br>";
            }   
        }   
    };
    
?>

And it's working fine with

*
**
***
****
*****

But then I need opposite loop first 4 then 3 then 2 then 1...

Where am I going wrong with this?



Solution 1:[1]

Just for fun. Try this:

$stars = 1;
for ($i = 0; $i < 9; $i++) {
    for ($s = 1; $s <= $stars; $s++) {
       echo "*";
    }
    echo "\n";

    $stars += ($i<4)?1:-1;   
}

And, for even more fun, one with just one for loop:

$stars = 0;
$starctr = 0;
for ($i = 0; $i < 25; $i++) {
    echo "*";

    if ($stars == $starctr) {
      echo "\n";

      $stars += ($i<14)?1:-1;
      $starctr = 0;
    } else {
      $starctr++;
    }
}

Solution 2:[2]

Can using nested for loop. Example:

$n = 5;
for($i = 1; $i <= $n; $i++){
    for($j = 1; $j <= $i; $j++){
        echo '*';
    }
    echo '<br />';
}
for($i = $n-1; $i >= 1; $i--){
    for($j = $i; $j >= 1; $j--){
        echo '*';
    }
    echo '<br />';
}

Another technique using array_fill(), array_map(), array_reverse()

$n = 5; $arr = array();
for($i = 1; $i <= $n; $i++){
   $arr[] = array_fill(0, $i, '*');
}
array_map(function($v){echo join('', $v) . '</br>';},$arr);
unset($arr[count($arr) - 1]); //remove last index value
array_map(function($v){echo join('', $v) . '</br>';},array_reverse($arr));

Solution 3:[3]

<?php
for($i=0;$i<=6;$i++){
    for($k=6;$k>=$i;$k--){
        echo " &nbsp;";
    }
    for($j=1;$j<=$i;$j++){
        echo "* &nbsp;";
    }
    echo "<br>";
}
for($i=5;$i>=1;$i--){
    for($k=6;$k>=$i;$k--){
        echo " &nbsp;";
    }
    for($j=1;$j<=$i;$j++){
        echo "* &nbsp;";
    }
    echo "<br>";
}
?>

Solution 4:[4]

This can be achieved with only 2 for loops.

$offset = 1;
for ($i = 1; $i > 0; $i += $offset)
{
    for($j = 1; $j <= $i; $j++){
        echo '*';
    }
    echo '<br />';

    if ($i === 5)
        $offset = -1;
}

Solution 5:[5]

 <?php

    $i = 1;
    $end = 5;
    $star = "*";

    for($i; $i <= $end; $i++){
       for($b=1; $b <= $i; $b++){
         echo $star;
       }

    };
    for($c=$send; $c>=2; $c-- ){
       for($d=$end; $d >= 2; $d--){
         echo $star;
       }
       echo "<br>";
    };   

?>

Solution 6:[6]

Using a single for loop:

$end = 5;
$out = array();

for ($i=0;$i<$end;++$i)
{
    $out[] = str_repeat('*', $i+1);
}
echo implode(PHP_EOL, $out).PHP_EOL;
array_pop($out);
$out = array_reverse($out);//remove last ****** <-- only one line with 5 stars
echo implode(PHP_EOL, $out).PHP_EOL;

Replace PHP_EOL with <br> if you want to, but this is the least loopy way to write this code I can think of

live demo

Solution 7:[7]

Here's a recursive attempt:

function ladder($n, $counter=1, &$acc=array())
{
    if ($counter == ($n*2)) {
        return implode($acc);    
    }   

    if ($counter <= $n) {
        $acc[$counter] = str_repeat('*', $counter) . "\n";
        $counter++;
    }   

    if ($counter > $n) {
        $diff = (int) $n-$counter;
        $acc[$counter] = str_repeat('*', $n+$diff) . "\n";
        $counter++;
    }   

    return ladder($n, $counter, $acc);
}

print_r(ladder(5));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Romisha Aggarwal
Solution 4 Jerodev
Solution 5 3Demon
Solution 6 Elias Van Ootegem
Solution 7