Skip to content

Commit 46f4160

Browse files
committed
feat(power): Add power module
1 parent 4798827 commit 46f4160

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

src/recursion-practice/power/power.js

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Power
2+
const power = (base, exponent) => {
3+
if (exponent === 0) {
4+
return 1;
5+
}
6+
return base * power(base, exponent - 1);
7+
};
8+
9+
// Power proper tail call
10+
const powerPTC = (base, exponent, resultSoFar = 1) => {
11+
if (exponent === 0) {
12+
return resultSoFar;
13+
}
14+
const newResultSoFar = resultSoFar * base;
15+
return powerPTC(base, exponent - 1, newResultSoFar);
16+
};
17+
18+
// Power continuous passing style
19+
const identity = x => x;
20+
const powerCPS = (base, exponent, cont = identity) => {
21+
if (exponent === 0) {
22+
return cont(1);
23+
}
24+
return powerCPS(base, exponent - 1, result => cont(result * base));
25+
};
26+
27+
// Power with trampolining
28+
const trampoline = fn => (...args) => {
29+
let result = fn(...args);
30+
31+
while (typeof result === 'function') {
32+
result = result();
33+
}
34+
35+
return result;
36+
};
37+
38+
const powerTrampoline = trampoline(function _power(
39+
base,
40+
exponent,
41+
resultSoFar = 1,
42+
) {
43+
if (exponent === 0) {
44+
return resultSoFar;
45+
}
46+
const newResultSoFar = resultSoFar * base;
47+
return () => powerPTC(base, exponent - 1, newResultSoFar);
48+
});
49+
50+
export { power, powerPTC, powerCPS, powerTrampoline };
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import each from 'jest-each';
2+
import { power, powerPTC, powerCPS, powerTrampoline } from './power';
3+
4+
[power, powerPTC, powerCPS, powerTrampoline].forEach(fn => {
5+
describe(`${fn.name}`, () => {
6+
each`
7+
base | exponent | expected
8+
${1} | ${0} | ${1}
9+
${1} | ${1} | ${1}
10+
${1} | ${2} | ${1}
11+
${2} | ${0} | ${1}
12+
${2} | ${1} | ${2}
13+
${2} | ${2} | ${4}
14+
${2} | ${4} | ${16}
15+
`.test(
16+
'should return $expected when called with $base and $exponent',
17+
({ base, exponent, expected }) => {
18+
expect(fn(base, exponent)).toBe(expected);
19+
},
20+
);
21+
});
22+
});

0 commit comments

Comments
 (0)