Skip to content

Instantly share code, notes, and snippets.

@Tahseenm
Created October 25, 2017 09:58
Show Gist options
  • Save Tahseenm/dce5c28cded413b0d5f6ea193f357171 to your computer and use it in GitHub Desktop.
Save Tahseenm/dce5c28cded413b0d5f6ea193f357171 to your computer and use it in GitHub Desktop.
Factorial using recursion
/* -------------------------------------------------------------------------- *\
* Utils
\* -------------------------------------------------------------------------- */
const isFunction = val => typeof val === 'function'
/**
* Trampoline
*/
const T = fn => (...args) => {
let result = fn(...args)
while (isFunction(result)) {
result = result()
}
return result
}
/* -------------------------------------------------------------------------- *\
* Factorial
\* -------------------------------------------------------------------------- */
/**
* Recursive Solution
* @example
* factorial(5)
* 5 * f(4)[ 4 * f(3)[ 3 * f(2)[ 2 * f(1)[ 1 ]]]]
* 5 * f(4)[ 4 * f(3)[ 3 * f(2)[ 2 * 1]]]
* 5 * f(4)[ 4 * f(3)[ 3 * 2]]
* 5 * f(4)[ 4 * 6]
* 5 * 24
* = 120
*/
const simpleFactorial = function factorial(n) {
if (n <= 1) return 1
return n * factorial(n - 1)
}
/**
* Tail call Optimized Recursive solution
*
* Left to Right multiplication
* @example
* factorial(5)
* f(5, 4) -> f(20, 3) -> f(60, 2) -> f(120, 1) -> 120
* = 120
*/
const optimizedFactorial = x => (function factorial(acc = 1, n = x) {
if (n <= 1) return acc
return factorial(n * acc, n - 1)
})()
/**
* Trampolined Recursive Solution for non Tail call optimized JS enviroments
*
* Left to Right multiplication
* @example
* factorial(5)
* f(5, 4) -> f(20, 3) -> f(60, 2) -> f(120, 1) -> 120
* = 120
*/
const trampolinedFactorial = x => T(function factorial(acc = 1, n = x) {
if (n <= 1) return acc
return () => factorial(n * acc, n - 1)
})()
/**
* Test
* Dont worry about exceeding maximum call stack in JS enviroment
*/
console.log(trampolinedFactorial(100800)) // -> Infinity
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment