Skip to content

Commit a9672bd

Browse files
authored
Merge pull request #59 from deveshidwivedi/main
Added an advance JS problem.
2 parents ccfe490 + 4574272 commit a9672bd

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

L-A/0014 Memoize II/MemoizeII.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
const RES = Symbol("result");
3+
4+
/**
5+
* @param {Function} fn
6+
*/
7+
function memoize(fn) {
8+
const globalCache = new Map();
9+
10+
return (...params) => {
11+
let currentCache = globalCache;
12+
for(const param of params) {
13+
if (!currentCache.has(param)) {
14+
currentCache.set(param, new Map());
15+
}
16+
currentCache = currentCache.get(param);
17+
}
18+
19+
if (currentCache.has(RES)) return currentCache.get(RES);
20+
21+
const result = fn(...params);
22+
23+
currentCache.set(RES, result);
24+
return result;
25+
}
26+
}

L-A/0014 Memoize II/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Memoize II
2+
[LeetCode Problem]https://leetcode.com/problems/memoize-ii/
3+
4+
Given a function fn, return a memoized version of that function.
5+
6+
A memoized function is a function that will never be called twice with the same inputs. Instead it will return a cached value.
7+
8+
fn can be any function and there are no constraints on what type of values it accepts. Inputs are considered identical if they are === to each other.
9+
10+
## Example 1:
11+
```javascript
12+
Input:
13+
getInputs = () => [[2,2],[2,2],[1,2]]
14+
fn = function (a, b) { return a + b; }
15+
Output: [{"val":4,"calls":1},{"val":4,"calls":1},{"val":3,"calls":2}]
16+
Explanation:
17+
const inputs = getInputs();
18+
const memoized = memoize(fn);
19+
for (const arr of inputs) {
20+
memoized(...arr);
21+
}
22+
23+
For the inputs of (2, 2): 2 + 2 = 4, and it required a call to fn().
24+
For the inputs of (2, 2): 2 + 2 = 4, but those inputs were seen before so no call to fn() was required.
25+
For the inputs of (1, 2): 1 + 2 = 3, and it required another call to fn() for a total of 2.
26+
```
27+
28+
## Example 2:
29+
```javascript
30+
Input:
31+
getInputs = () => [[{},{}],[{},{}],[{},{}]]
32+
fn = function (a, b) { return ({...a, ...b}); }
33+
Output: [{"val":{},"calls":1},{"val":{},"calls":2},{"val":{},"calls":3}]
34+
Explanation:
35+
Merging two empty objects will always result in an empty object. It may seem like there should only be 1 call to fn() because of cache-hits, however none of those objects are === to each other.
36+
```
37+
38+
39+
## Example 3:
40+
```javascript
41+
Input:
42+
getInputs = () => { const o = {}; return [[o,o],[o,o],[o,o]]; }
43+
fn = function (a, b) { return ({...a, ...b}); }
44+
Output: [{"val":{},"calls":1},{"val":{},"calls":1},{"val":{},"calls":1}]
45+
Explanation:
46+
Merging two empty objects will always result in an empty object. The 2nd and 3rd third function calls result in a cache-hit. This is because every object passed in is identical.
47+
```
48+
49+
### Constraints:
50+
```javascript
51+
1 <= inputs.length <= 105
52+
0 <= inputs.flat().length <= 105
53+
inputs[i][j] != NaN
54+
```
55+
56+
## Approach:
57+
Map is perfect for storing single argument. Each consecutive argument must have cache based on previous argument, which will form a tree like structure, like this:
58+
```javascript
59+
fn(1,3,4) // { 1: { 3: { 4: {}}}};
60+
fn(1,4,3) // { 1: { 3: { 4: {}}, 4: { 3: {}}}};
61+
```
62+
The only problem, is how do we store our result. It's been never stated, that memoized function will be called with the same amount of arguments every time. We need a way to store our result anywhere on the path and also make sure that it will never be misteaken with argument. Here is example.
63+
```javascript
64+
fn(1,3) // { 1: { 3: 4}};
65+
-> 4
66+
fn(1) // { 1: { 3: 4}};
67+
-> { 3: 4 } // returning cache branch as result
68+
```
69+
There are different aproaches to overcome this. But since every Symbol() call is guaranteed to return a unique Symbol we can use it to store actual result with guarantee, that it will never match any argument.
70+
71+
## Problem Added By
72+
73+
- [deveshidwivedi](https://github.com/deveshidwivedi)
74+
75+
76+
77+
## Contributing
78+
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
79+
80+
Please make sure to update tests as appropriate.

0 commit comments

Comments
 (0)