First I will propose only some simple changes to make the code more readable.
1. add #!/bin/bash
as first line then it is guaranteed that bash is used
2. use consistent indentation
3. when you do arithmetic evaluation you don't need the $
character to evaluate the variables,
4. use consistent spacing to structure expressions, e.g. (( j=max; j>=i; j-- ))
5. instead of expr
use $((...))
this is more readable but has other advantages, too.
6. echo ""
hase the same effect as echo
, so use the latter, it is more clear
7. echo "Total No. of stars :" $sum
is the same as echo "Total No. of stars : $sum"
, but the latter is more clear, so use the latter.
8. Initialize variables. They may be set outside the script to a wrong value.
#!/bin/bash
echo "enter the mininum number of stars"
read min
echo "enter the maximum number of stars"
read max
sum=0
for (( i=min; i<=max; i++ )); do
for (( j=max; j>=i; j-- )); do
echo -n " "
done
for (( c=1; c<=i; c++ )); do
echo -n " *"
sum=$(( sum+1 ))
done
echo
done
d_max=$(( max-1 ))
for (( i=d_max; i>=min; i-- )); do
for (( j=i; j<=d_max; j++ )); do
if (( j==d_max )); then
echo -n " "
fi
echo -n " "
done
for (( c=1; c<=i; c++ )); do
echo -n " *"
sum=$(( sum+1 ))
done
echo
done
echo "Total No. of stars : $sum"
This loop is executed d_max-i+1 mal, and d_max-i+2 times " " is printed.
for (( j=i; j<=d_max; j++ )); do
if (( j==d_max )); then
echo -n " "
fi
echo -n " "
done
So use the simpler loop to print d_max-i+2 times " ".
for (( j=i; j<=d_max+1; j++ )); do
echo -n " "
done
Instead of
for (( c=1; c<=i; c++ )); do
echo -n " *"
sum=$(( sum+1 ))
done
use the simpler
for (( c=1; c<=i; c++ )); do
echo -n " *"
done
sum=$(( sum+i ))
You have 4 times a similar block of code. Is it possible to replace it by a function? Yes!
print_from_to(){
str=$1
from=$2
to=$3
for (( t=$from; t<=$to; t++ )); do
echo -n $str
done
}
So we have the following code now
#!/bin/bash
print_from_to(){
str=$1
from=$2
to=$3
for (( t=$from; t<=$to; t++ )); do
echo -n $str
done
}
echo "enter the mininum number of stars"
read min
echo "enter the maximum number of stars"
read max
sum=0
for (( i=min; i<=max; i++ )); do
print_from_to " " $i $max
print_from_to " *" 1 $i
sum=$(( sum+i ))
echo
done
d_max=$(( max-1 ))
for (( i=d_max; i>=min; i-- )); do
print_from_to " " $i $((d_max+1))
print_from_to " *" 1 $i
sum=$(( sum+i ))
echo
done
echo "Total No. of stars : $sum"
All in all you do a lot of echo
commands, I think
$$2\cdot max\cdot (max-min+1).$$
You can simplify your program. Note that for the first half of your lines the next line to be print can be constructed out of the previous line by removing ' '
from the beginning and adding ' *'
at the end.
line=${line# } # remove leading blank
line="$line *" # add blank and asterisk at the end
The second half of the lines can be constructed by adding a ' '
at the beginning and removing ' *'
from the end.
line=" $line" # add blank at the beginning
line=${line% *} # remove trailing blank and asterisk