I have a program that prints the star pattern.
Starr Pattern is:
*
*
*
*
* * * * * * * * *
*
*
*
*
My code is:
$n=5;
for($i=0; $i<$n; $i++){
for($k=$n-$i; $k>0; $k--){
echo ' '.' ';
}
for($j=0; $j< ($tot = $i+1); $j++){
if($i==$j && $tot<$n){
echo '* ';
}else{
if($tot<$n){
echo ' '.' ';
}else{
echo '* ';
}
}
}
if($i == ($n-1)){
for($l=$n-1; $l>0;$l--){
echo '* ';
}
}
echo '<br/>';
}
for($i=0;$i<$n;$i++){
for($k=$n-$i; $k>0; $k--){
echo ' '.' ';
}
for($j=0; $j< ($tot = $i+1); $j++){
if($i==$j && $tot<$n){
echo '* ';
}else{
echo ' '.' ';
}
}
echo '<br/>';
}
My question is that how can I calculate the complexity of this code?
And also Is there a good way to reduce loops?
2 Answers 2
It looks nice. Can you please make me understand how it works
For example
function f($n){$s='';$b=str_pad('*',($m=$n*2+1),' ',2);for($i=0;$i<$m;++$i)$s.=($i==$n)?str_repeat('*',$m):$b;return chunk_split($s, $m);}
Output
*
*
*
*
*
***********
*
*
*
*
Let me write it in a way that is easier to see
$n = 5;
$row_len = $n*2+1;
$output = '';
//pad $n spaces on each side of *
$default = str_pad('*',$row_len,' ',STR_PAD_BOTH); //is = " * "
//loop once for each vertical row (same as width)
for($i=0;$i<$row_len;++$i){
if($i==$n){
//do the center line all *'s
$output .= str_repeat('*',$row_len);//is = "***********"
}else{
//use the default line from above
$output .= $default;
}
}
//now we have a single line that is the length squared so we can chunk it
//into equal parts, to make a square
echo chunk_split($output, $row_len); //is = " * * ***********"
Basically we can create the " * "
row by using string pad. Because we can pad spaces on both sides of a *
up to the length of a row ($n*2)+1
.
Then the center row, is just *
so we can use string repeat to the length of the row for that line.
Last we take our big huge line of spaces and *
and split it into chunks (\n
) on the length of our row we want.
-
2\$\begingroup\$ Hope that helps explain it a bit better. Basically were exploiting the fact that it conforms to a set pattern. So for example we know if
$n
is5
to do 5 spaces a star and 5 more spaces($n*2)+1
So we can just use String Pad for that and pad 5 spaces on each side. String Pad takes the total length of the string you want. So it's the full length of the row. \$\endgroup\$ArtisticPhoenix– ArtisticPhoenix2019年03月22日 15:18:30 +00:00Commented Mar 22, 2019 at 15:18 -
\$\begingroup\$ I think your output is skinnier than the OPs. \$\endgroup\$mickmackusa– mickmackusa2019年03月26日 21:05:23 +00:00Commented Mar 26, 2019 at 21:05
-
\$\begingroup\$ @mickmackusa - it is. I didn't put a space between
* *
the stars. Shouldn't be too hard to fix, but it adds a variable in. So I was too lazy .... lol \$\endgroup\$ArtisticPhoenix– ArtisticPhoenix2019年03月26日 21:26:29 +00:00Commented Mar 26, 2019 at 21:26 -
\$\begingroup\$ DEREGISTERED!!!! What have you done, you mad man! What causes a person to do that?!? An occupational requirement? Witness protection? \$\endgroup\$mickmackusa– mickmackusa2019年04月15日 01:58:28 +00:00Commented Apr 15, 2019 at 1:58
Here's my array-functional spin on the task. It is not likely to be faster than @ArtisticPhoenix's solution, but it provides the desired output without loop constructs or conditions. ...just different for the sake of being different.
The process generates a full-sized array of strings that "looks" like a vertical stroke of asterisks, then replaces the middle element with a horizontal stroke element.
Code: (Demo)
$size = 7; // circumference not radius
$vertical = str_pad('*', $size * 2 - 1, ' ', STR_PAD_BOTH); // row w/ central symbol
$result = array_fill(0, $size, $vertical); // top-to-bottom stroke of symbols
$result[$size / 2] = implode(' ', array_fill(0, $size, '*')); // left-to-right stroke of symbols
echo implode(PHP_EOL, $result);
For improved readability, I've declared the single-use variable $vertical
.
Output: (highlight the text with your cursor to see that the pattern has no unnecessary trailing spaces in any line.)
*
*
*
* * * * * * *
*
*
*
*notice that I am not bothering to floor()
the "horizontal stroke" element key, because php casts float keys to integers. https://www.php.net/manual/en/language.types.array.php
+
to me, guess it's just semantics.... \$\endgroup\$good way to reduce loops
yesstr_repeat
andchunk_split
you can see this example (a code golf answer I did) of what you can do with these 2, codegolf.stackexchange.com/questions/171679/… basically you could make one long string with the space or*
by using str_repeat and then split it into rows with chunk_split \$\endgroup\$function f($n){$s='';$b=str_pad('*',($m=$n*2+1),' ',2);for($i=0;$i<$m;++$i)$s.=($i==$n)?str_repeat('*',$m):$b;return chunk_split($s, $m);}
Sandbox \$\endgroup\$