PHP Question: PHP Script Shape

Question

Write a PHP script that will print out the following text in the correct diamond shape.

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

 

 

 

 

 

 

 

 

 

Answer

The diamond shape consists of 10 'levels' of stars. Each level consists of one or more stars and some whitespace that pushes the middle star into the middle of the line. Each line must also consist of an odd number of stars as an even number of starts can't have a middle star.

What we need to do to draw the shape is to loop from 1 until we reach the middle of the star and then go back down until we reach 1 again. Because we are only using odd numbers we can simply use 10 as the count of the number of levels and then increment by 2 until we reach that value before going back down the numbers again. The only thing we need to change when going down the levels is a check for an odd or even number of levels. If the number is even then we need to take 1 away so that we are still counting in odd numbers. The whitespace can be worked out by subtracting the increment value by the number of levels.

Rather than doing individual loops over the whitespace and star values we can use the PHP str_pad() function. The second parameter is the length that the string must be and the third parameter is a custom pad value, which we either put a space or a star. The first parameter is is string we need to pad, but as this isn't going to be used here we can just put a blank string.

We therefore end up with this code.

// Top of star
for ($i = 1; $i <= $levels; $i = $i + 2) {
  $whitespace = ($levels - $i / 2);
  echo str_pad('', $whitespace, ' ') . str_pad('', $i, '*') . "\n";
}

// Odd or even number of levels?
if ($levels % 2 == 0) {
  $downlevels = $levels - 1; 
} else {
  $downlevels = $levels; 
}

// Bottom of star
for ($i = $downlevels; $i >= 0; $i = $i - 2) {
  $whitespace = ($levels - $i / 2);
  echo str_pad('', $whitespace, ' ') . str_pad('', $i, '*') . "\n";
}

Some of you might have noticed that we are doing the same thing twice here. Essentially, the second loop is repeating the work done by the first loop, just in the opposite direction. What we can do to improve the efficiancy of this code is remove the second loop and make the first loop create a serires of array elements. We can then use a combination of the PHP implode() and array_reverse() functions to print the output from a single run of the loop. Changing the above code to incorporate these functions we get the following code.

$levels = 10;
$output = array();

for ($i = 1; $i <= $levels; $i = $i + 2) {
  $whitespace = ($levels - $i / 2);
  $output[] = str_pad('', $whitespace, ' ') . str_pad('', $i, '*');
}

echo implode("\n", $output);
echo "\n";
echo implode("\n", array_reverse($output));
echo "\n";

This prints out the following.

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

We can do some final tidying up of the output generated by removing the large amount of whitespace on the left hand side of the shape. We do this by creating a whitespace factor variable that is half of the number of levels, and subtracting this from the amount of whitespace generated. We can also wrap the code in a function call to make things more convenient when running.

function draw_diamond($levels) {
  $whitespaceFactor = $levels/2;

  $output = array();

  for ($i = 1; $i <= $levels; $i = $i + 2) {
    $whitespace = ($levels - $i / 2) - $whitespaceFactor;
    $output[] = str_pad('', $whitespace, '-') . str_pad('', $i, '*');
  }

  echo implode("\n", $output);
  echo "\n";
  echo implode("\n", array_reverse($output));
  echo "\n";
}

draw_diamond(10);

Running the above code gives us the following output, which is exactly the shape we are looking for.

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

 

Comments

Nice Code

Permalink
what about a half diamond just like this 1 12 123 1234 12345 123456 12345 1234 123 12 1 what's the code?
Permalink
'; echo " "; } for($i=8;$i>=3;$i--) { for($k=1;$k<=$i-3;$k++) { echo $k; } echo '
'; } ?>
Permalink
______________* _____________ *** ____________ ***** ___________ ******* __________ ********* _________*********** ________************* _______*************** _______*************** ________************* _________*********** __________********* ___________******* ____________***** _____________*** _____________* ur ans is showing this and i don't want "_" i want white space so please help me
Permalink
Corrected. You just needed to alter the str_pad() function a little.
Name
Philip Norton
Permalink
=$i;$j--) { echo " "; } for($j=0;$j<=$i;$j++) { echo "*"; } echo "
"; } for($i=0;$i<=5;$i++) { for($j=1;$j<=$i+1;$j++) { echo " "; } for($j=5;$j>=$i;$j--) { echo "*"; } echo "
"; } ?>
Hope This Helps :P
Permalink
can aynone tell me on how to create an hourglass patter? it will be great for me to follow. thanks
Permalink
i just cannot seem to find a pattern like that, your help will be appreciated.
Permalink
Using recursive function.=DIAMOND_SIZE) { run($star, $rows, 0); } else { run($star, $rows); } } } function printRow($num, $type=STAR) { if ($type === STAR) { for ($i=0; $i<$num; $i++) { echo " *"; } } else { for ($i=0; $i<$num; $i++) { echo " "; } } } ?>
Permalink

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
1 + 0 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.