Compute factorial of positive integer using only built-ins

factorial() { local N; eval let N=1 N*={1..$1}; echo "$N"; }

November 29, 2019CK

Explanation

Using let, this takes advantage of its mathematical functions and argument-based variable assignments to serially overwrite the last known value of N with the product of N and the next integer generated by the expansion of {1..$1} into a list of incremental numbers.

Since the sequence expression {x..y} only works with literal values, {1..$1} would not be expanded to a sequence of numbers. For example when $1 is 3, then {1..$1} expands to {1..3} instead of the sequence 1 2 3. This is the reason we use eval, so that in this example evaluating the expression {1..3} expands to the sequence 1 2 3.

The final expression executed by the shell after all expansions are applied is equivalent to:

let N=1 N=N*1 N=N*2 N=N*3 ... N=N*$1

Related one-liners

Recursively compute factorial of positive integer using only built-ins

factorial() ( IFS=\*; let N=$1-1 k="$*" && factorial "$N" "$k" || echo ${2-1} )

November 25, 2019CK