public
Created

Computing Euler's number in pure bash

  • Download Gist
gistfile1.sh
Shell
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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
#!/bin/bash
 
function numerator() {
local __resultvar=$1
local fraction=$2
if [[ $fraction =~ (.*)/.* ]] ; then
eval $__resultvar="'${BASH_REMATCH[1]}'"
fi
}
function denominator() {
local __resultvar=$1
local fraction=$2
if [[ $fraction =~ .*/(.*) ]] ; then
eval $__resultvar="'${BASH_REMATCH[1]}'"
fi
}
function multiply() {
local __resultvar=$1
local fraction1=$2
local fraction2=$3
local n
local d
numerator a $fraction1
denominator b $fraction1
numerator c $fraction2
denominator d $fraction2
let "n=a*c"
let "d=b*d"
eval $__resultvar="$n/$d"
 
}
function sum() {
local __resultvar=$1
local fraction1=$2
local fraction2=$3
 
#a/b+c/d is
#(ad+bc)/bd
numerator a $fraction1
denominator b $fraction1
numerator c $fraction2
denominator d $fraction2
let "sum_n=a*d+b*c"
let "sum_d=b*d"
eval $__resultvar="$sum_n/$sum_d"
 
}
function to_dec {
local __resultvar=$1
local r
local accum
numerator n $2
denominator d $2
let r=n/d
let n=n-r*d
let n=n*10
let precision=0
accum="${r}."
while [[ $precision -lt 12 ]];do
let r=n/d
let n=n-r*d
accum="${accum}${r}"
let n=n*10
let precision=precision+1
done
eval $__resultvar="$accum"
 
}
common_prefix() {
local n=0
while [[ "${1:n:1}" == "${2:n:1}" ]]; do
((n++))
done
echo $n
}
 
function euler() {
local accum=1/1
local term=1/1
local numer
local denom
local result
local new_result
for n in $(seq 1 13);do
multiply term $term 1/$n
sum accum $accum $term
#reduce
numerator numer $accum
denominator denom $accum
gcd common $numer $denom
let numer=numer/common
let denom=denom/common
accum=$numer/$denom
to_dec new_result $accum
if [[ $(common_prefix $new_result $result) -ge $(($1+2)) ]]; then
echo $result
return
fi
result=$new_result
done
echo "Couldn't get that many digits. Sorry"
}
function gcd() {
local __resultvar=$1
 
local tmp
local num1=$2
local num2=$3
while [[ $num1 -gt 0 ]];do
let "tmp=num1"
let "num1=num2%num1"
let "num2=tmp"
done
eval $__resultvar="$num2"
}
euler $1

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.