Bash script can be very powerful. In Linux shells, with BASH script, it is possible to solve maths problems easily. It is a full programming language and arithmetic operations are just one shining aspect.
The integer factorial is a simple maths problem. Given a integer N and compute the value N! = 1 x 2 x 3 x … N. However, if the given number is large and the result will be too big to hold in a single variable.
Let’s have a look at the script result first, which runs at Linux (Ubuntu).
1 2 3 4 5 6 7 8 9 10 | root@uploadbeta:/bash# ./frac.sh Please Input N > = -23423 Please Input N > = 5 5! = 120 root@uploadbeta:/bash# ./frac.sh Please Input N > = 30 30! = 265252859812191058636308480000000 root@uploadbeta:/bash# |
root@uploadbeta:/bash# ./frac.sh Please Input N > = -23423 Please Input N > = 5 5! = 120 root@uploadbeta:/bash# ./frac.sh Please Input N > = 30 30! = 265252859812191058636308480000000 root@uploadbeta:/bash#
So, let’s break the script into parts. First, we need to check the input number, make sure it is valid and doesn’t get too big.
1 2 3 4 5 6 7 8 9 | #!/bin/bash typeset -i MaxN=100 while : do echo -n "Please Input N > = " read N [ $N -lt 1 -o $N -gt "$MaxN" ] || break done echo -n "$N! = " |
#!/bin/bash typeset -i MaxN=100 while : do echo -n "Please Input N > = " read N [ $N -lt 1 -o $N -gt "$MaxN" ] || break done echo -n "$N! = "
The endless loop will break only if the input falls into the correct range, which is between 1 to 100 inclusive. Then we need to define a array to hold the result,
1 2 3 4 5 6 7 8 9 | typeset -i result function init { for (( i=0;i<$MaxN;i++ )) do (( result[$i]=0 )) done (( result[0]=1 )) } |
typeset -i result function init { for (( i=0;i<$MaxN;i++ )) do (( result[$i]=0 )) done (( result[0]=1 )) }
The init function will clear the array to zeros and set the first element to one. So the result is read in the reverse order i.e. the first position denotes the ‘ones’ and the second position denotes the ‘tens’. In Linux BASH shell, we use double brackets to make arithmetic operations.
To print the result, we just simply loop the arrays. Make sure to skip the zeros and print it from right to left.
1 2 3 4 5 6 7 8 9 10 11 12 13 | function out { typeset -i j=$MaxN-1 until [[ ${result[$j]} -ne 0 ]] do (( j-- )) done for (( i=$j;i>=0;i-- )) do echo -n ${result[$i]} done echo -e "\n" } |
function out { typeset -i j=$MaxN-1 until [[ ${result[$j]} -ne 0 ]] do (( j-- )) done for (( i=$j;i>=0;i-- )) do echo -n ${result[$i]} done echo -e "\n" }
And the computation part is done in function work. The outer loop multiples each number from 2. And the inner 2 loops will multiple each digit in the result and make corresponding adjustments.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function work { for (( i=2;i<=$N;i++ )) do for (( j=0;j<$MaxN;j++ )) do (( result[$j]*=$i )) done for (( j=0;j<$MaxN-1;j++ )) do (( result[$j+1]+=result[$j]/10 )) (( result[$j]%=10 )) done done } |
function work { for (( i=2;i<=$N;i++ )) do for (( j=0;j<$MaxN;j++ )) do (( result[$j]*=$i )) done for (( j=0;j<$MaxN-1;j++ )) do (( result[$j+1]+=result[$j]/10 )) (( result[$j]%=10 )) done done }
The over source code is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #!/bin/bash typeset -i MaxN=100 # check input while : do echo -n "Please Input N > = " read N [ $N -lt 1 -o $N -gt "$MaxN" ] || break done echo -n "$N! = " typeset -i result # initialization function init { for (( i=0;i<$MaxN;i++ )) do (( result[$i]=0 )) done (( result[0]=1 )) } # print result function out { typeset -i j=$MaxN-1 until [[ ${result[$j]} -ne 0 ]] do (( j-- )) done for (( i=$j;i>=0;i-- )) do echo -n ${result[$i]} done echo -e "\n" } # computation function work { for (( i=2;i<=$N;i++ )) do for (( j=0;j<$MaxN;j++ )) do (( result[$j]*=$i )) done for (( j=0;j<$MaxN-1;j++ )) do (( result[$j+1]+=result[$j]/10 )) (( result[$j]%=10 )) done done } # free variables function depose { unset i unset j unset result unset MaxN unset N } # entry point init work out depose |
#!/bin/bash typeset -i MaxN=100 # check input while : do echo -n "Please Input N > = " read N [ $N -lt 1 -o $N -gt "$MaxN" ] || break done echo -n "$N! = " typeset -i result # initialization function init { for (( i=0;i<$MaxN;i++ )) do (( result[$i]=0 )) done (( result[0]=1 )) } # print result function out { typeset -i j=$MaxN-1 until [[ ${result[$j]} -ne 0 ]] do (( j-- )) done for (( i=$j;i>=0;i-- )) do echo -n ${result[$i]} done echo -e "\n" } # computation function work { for (( i=2;i<=$N;i++ )) do for (( j=0;j<$MaxN;j++ )) do (( result[$j]*=$i )) done for (( j=0;j<$MaxN-1;j++ )) do (( result[$j+1]+=result[$j]/10 )) (( result[$j]%=10 )) done done } # free variables function depose { unset i unset j unset result unset MaxN unset N } # entry point init work out depose
“Where there is a shell, there is a way!” – Happy Scripting!
–EOF (The Ultimate Computing & Technology Blog) —
loading...
Last Post: BASH Script to Solve 8 Queen Problem
Next Post: Test Javascript On/Off in PHP via POST