Hi, this is a great project. Thanks.
I have a concern that I would like to share.
For instance, looking at /algorithms/math/factorial
which is one of the most basic math topic:
https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/factorial
I found 2 implementations:
factorial.js
export default function factorial(number) {
let result = 1;
for (let i = 2; i <= number; i += 1) {
result *= i;
}
return result;
}
factorialRecursive.js
export default function factorialRecursive(number) {
return number > 1 ? number * factorialRecursive(number - 1) : 1;
}
factorial.js
is a code of Procedural/Imperative programming style, and uses mutable variables.
factorialRecursive.js
is recursive, and can be said functional programming style, immutable. Alghouth this is a typical implementation which I can see everywhere, in terms of "Big O notations". this is rather anti-pattern.
A better or I would say, a proper way is,
factorialFunctional.js
//[...Array(5).keys()]
//-> [ 0, 1, 2, 3 ,4 ]
const natural = n => {
const arr0 = [...Array(n + 1).keys()];
const [first, ...arr] = arr0;
return arr;
};
console.log(
natural(5) //[ 1, 2, 3, 4, 5 ]
);
function factorialFunctional(number) {
const list = number < 1
? [1]
: natural(number)
const multiply = (a, b) => a * b;
return list.reduce(multiply);
}
console.log(
factorialFunctional(5)//120
);
This is as efficient as the factorial.js
in terms of "Big O notations", and immutable.
I think when algorithms are presented, it's significantly important to clarify what kind of programming paradigm the algorithms are based on.
Currently, it seems the contributions are updated randomly without formal classification for them, and I think it's a good idea to show a guideline in the README that to clarify which paradigm every algorithm belongs to. In this manner, a contributors notice "oh, here, there is no Functional or Imperative pattern yet, so I will add.."
Thanks.