Home>

### linux - [bash] [shell] i want to optimize code

■ Question

I wrote code for the following problems, and the test passed, but when I tried to run it, I got an "Execution Timed Out (12000 ms)" message.
Since it works in tests, you probably need to optimize your code.
I'd like to know how to rewrite this code, and if there is something wrong with the grammar.

■ Site in question

https://www.codewars.com/kata/growth-of-a-population/train/shell

■ Problem

A town has "\$1" inhabitants. The population increases by "\$2"% every year, and "\$3" new residents live every year.
How many years does the town need to make residents more than "\$4"?

At the end of the first year there will be:
1000 + 1000 * 0.02 + 50 =>1070 inhabitants

At the end of the 2nd year there will be:
1070 + 1070 * 0.02 + 50 =>1141 inhabitants (number of inhabitants is an integer)

At the end of the 3rd year there will be:
1141 + 1141 * 0.02 + 50 =>1213

It will need 3 entire years.

* If the percentage parameter is 2, you need to convert it to 0.02.

``````#!/bin/bash
nbYear () {
human = \$1
year = 0
inc = `echo" scale = 5;\$2/100 "| bc` #convert to percentage
while true
do
human = `echo" \$human + \$human * \$inc + \$3 "| bc | sed s/\. [0-9,] * \$// g` # round down
year = \$((\$year + 1))
if ["\$(echo" \$human>= \$4 "| bc)" -eq 1];then
echo \$year
break
fi
done
}
nbYear \$1 \$2 \$3 \$4``````

I don't think it's too slow.
Also, the`if`condition is unclear. I think this would be an error. Did you attach a different code?

There is no need to use bc, so you can use bash's calculation function only.

``````#!/bin/bash
nbYear () {
year = 0
human = \$1
inc = \$2
come = \$3
limit = \$4
while true
do
let human + = human * inc/100 + come
let year ++
if [\$human -ge \$limit];then
echo \$year
break
fi
done
}
nbYear \$1 \$2 \$3 \$4``````

Since it is not checked whether the argument is valid (4 numbers), an invalid argument is an infinite loop.

``#Truncate after decimal point``

There is a full-width space before the comment.

Further, if ... then condition judgment is

``if [\$human -ge \$4];then``
Is

not good?

Or if you want to use bc, if you let bc do it all, you can do it in one process.

If you can only do bash's computing power,

``````#!/bin/bash
nbYear () {
total = \$1
percent = \$2
inc = \$3
limit = \$4
year = \$([[\$# -eq 5]]&&echo \$5 || echo 0)
percent_inc = \$((\$total * 100 * \$percent/10000))
total = \$((\$total + \$percent_inc + \$inc))
year = \$((year + 1))
echo "\$year: total = \$total (percent = \$percent_inc, inc = \$inc)"
if [[\$total -ge \$limit]];then
echo "Over: \$year on Humans is \$total"
else
nbYear \$total \$percent \$inc \$limit \$year
fi
}
nbYear \$1 \$2 \$3 \$4``````
Is it

?
Since it doesn't go through bc, it doesn't consider a small number at all, and shells are rounded down, so it is more straightforward to handle those that can be rounded down like the number of people.

Since no error is detected, I think that I will die by looping at the upper limit of bash and causing segmentation.

Result:

``````# sh test.sh 1000 2 50 1200
1: total = 1070 (percent = 20, inc = 50)
2: total = 1141 (percent = 21, inc = 50)
3: total = 1213 (percent = 22, inc = 50)
Over: 3 on Humans is 1213``````