PHP Question: PHP Script Shape

1st May 2011

Question

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

  1. *
  2. ***
  3. *****
  4. *******
  5. *********
  6. *********
  7. *******
  8. *****
  9. ***
  10. *

 

 

 

 

 

 

 

 

 

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.

  1. // Top of star
  2. for ($i = 1; $i <= $levels; $i = $i + 2) {
  3. $whitespace = ($levels - $i / 2);
  4. echo str_pad('', $whitespace, ' ') . str_pad('', $i, '*') . "\n";
  5. }
  6.  
  7. // Odd or even number of levels?
  8. if ($levels % 2 == 0) {
  9. $downlevels = $levels - 1;
  10. } else {
  11. $downlevels = $levels;
  12. }
  13.  
  14. // Bottom of star
  15. for ($i = $downlevels; $i >= 0; $i = $i - 2) {
  16. $whitespace = ($levels - $i / 2);
  17. echo str_pad('', $whitespace, ' ') . str_pad('', $i, '*') . "\n";
  18. }

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.

  1. $levels = 10;
  2. $output = array();
  3.  
  4. for ($i = 1; $i <= $levels; $i = $i + 2) {
  5. $whitespace = ($levels - $i / 2);
  6. $output[] = str_pad('', $whitespace, ' ') . str_pad('', $i, '*');
  7. }
  8.  
  9. echo implode("\n", $output);
  10. echo "\n";
  11. echo implode("\n", array_reverse($output));
  12. echo "\n";

This prints out the following.

  1. *
  2. ***
  3. *****
  4. *******
  5. *********
  6. *********
  7. *******
  8. *****
  9. ***
  10. *

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.

  1. function draw_diamond($levels) {
  2. $whitespaceFactor = $levels/2;
  3.  
  4. $output = array();
  5.  
  6. for ($i = 1; $i <= $levels; $i = $i + 2) {
  7. $whitespace = ($levels - $i / 2) - $whitespaceFactor;
  8. $output[] = str_pad('', $whitespace, '-') . str_pad('', $i, '*');
  9. }
  10.  
  11. echo implode("\n", $output);
  12. echo "\n";
  13. echo implode("\n", array_reverse($output));
  14. echo "\n";
  15. }
  16.  
  17. draw_diamond(10);

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

  1. *
  2. ***
  3. *****
  4. *******
  5. *********
  6. *********
  7. *******
  8. *****
  9. ***
  10. *

 

Comments

Permalink

Nice Code

Submitted by Onkar on Sat, 04/28/2012 - 13:05

Permalink
what about a half diamond just like this 1 12 123 1234 12345 123456 12345 1234 123 12 1 what's the code?

Submitted by john on Tue, 12/03/2013 - 06:41

Permalink
  1. <?php for($i=1;$i<=6;$i++)
  2. {
  3. for($j=1;$j<=$i;$j++)
  4. {
  5. echo $j;
  6. }
  7. echo '<br?>';
  8. echo " ";
  9. }
  10. for($i=8;$i>=3;$i--)
  11. {
  12. for($k=1;$k';
  13. }
  14. ?>

Submitted by s on Wed, 02/19/2014 - 06:59

Permalink
______________* _____________ *** ____________ ***** ___________ ******* __________ ********* _________*********** ________************* _______*************** _______*************** ________************* _________*********** __________********* ___________******* ____________***** _____________*** _____________* ur ans is showing this and i don't want "_" i want white space so please help me

Submitted by mukesh on Wed, 08/03/2016 - 12:41

Permalink
Corrected. You just needed to alter the str_pad() function a little.

Submitted by philipnorton42 on Wed, 08/03/2016 - 14:04

Permalink
  1. <?php for($i=0;$i<=6;$i++)
  2. {
  3. for($j=5;$j?>=$i;$j--)
  4. { echo "&nbsp";
  5. }
  6.  
  7.  
  8. for($j=0;$j";
  9. }
  10.  
  11. for($i=0;$i=$i;$j--)
  12.  
  13. { echo "*";
  14. }
  15. echo "<br />";
  16. }
  17.  
  18. ?>
Hope This Helps :P

Submitted by Usama Altaf on Fri, 03/10/2017 - 19:19

Permalink
can aynone tell me on how to create an hourglass patter? it will be great for me to follow. thanks

Submitted by Ace Aroon on Thu, 04/20/2017 - 14:22

Permalink
i just cannot seem to find a pattern like that, your help will be appreciated.

Submitted by Ace Aroon on Thu, 04/20/2017 - 14:23

Permalink
Using recursive function.
  1. <?php define("STAR", 1);
  2. define("SPACE", 2);
  3. define("DIAMOND_SIZE", 10);
  4.  
  5. run();
  6.  
  7. function run($star=1, $rows=1, $up=1)
  8. {
  9. $total_rows = (DIAMOND_SIZE * 2) - 1;
  10. $space = DIAMOND_SIZE - $star;
  11.  
  12. printRow($space, SPACE);
  13. printRow($star, STAR);
  14. echo "\n";
  15.  
  16. $rows++;
  17. if ($rows <= $total_rows) {
  18. $star = ($up) ? $star+1 : $star-1;
  19. if ($rows?>=DIAMOND_SIZE) {
  20. run($star, $rows, 0);
  21. } else {
  22. run($star, $rows);
  23. }
  24. }
  25. }
  26.  
  27.  
  28. function printRow($num, $type=STAR)
  29. {
  30. if ($type === STAR) {
  31. for ($i=0; $i

Submitted by SG on Wed, 09/13/2017 - 08:18

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.