Skip to content

Commit baef259

Browse files
authored
Added tasks 2630-2637
1 parent 60095e4 commit baef259

File tree

15 files changed

+682
-0
lines changed

15 files changed

+682
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
2630\. Memoize II
2+
3+
Hard
4+
5+
Given a function `fn`, return a **memoized** version of that function.
6+
7+
A **memoized **function is a function that will never be called twice with the same inputs. Instead it will return a cached value.
8+
9+
`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.
10+
11+
**Example 1:**
12+
13+
**Input:**
14+
15+
getInputs = () => [[2,2],[2,2],[1,2]]
16+
17+
fn = function (a, b) { return a + b; }
18+
19+
**Output:** [{"val":4,"calls":1},{"val":4,"calls":1},{"val":3,"calls":2}]
20+
21+
**Explanation:**
22+
23+
const inputs = getInputs();
24+
const memoized = memoize(fn);
25+
for (const arr of inputs) {
26+
memoized(...arr);
27+
}
28+
29+
For the inputs of (2, 2): 2 + 2 = 4, and it required a call to fn().
30+
31+
For the inputs of (2, 2): 2 + 2 = 4, but those inputs were seen before so no call to fn() was required.
32+
33+
For the inputs of (1, 2): 1 + 2 = 3, and it required another call to fn() for a total of 2.
34+
35+
**Example 2:**
36+
37+
**Input:**
38+
39+
getInputs = () => [[{},{}],[{},{}],[{},{}]]
40+
41+
fn = function (a, b) { return ({...a, ...b}); }
42+
43+
**Output:** [{"val":{},"calls":1},{"val":{},"calls":2},{"val":{},"calls":3}]
44+
45+
**Explanation:** 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.
46+
47+
**Example 3:**
48+
49+
**Input:**
50+
51+
getInputs = () => { const o = {}; return [[o,o],[o,o],[o,o]]; }
52+
53+
fn = function (a, b) { return ({...a, ...b}); }
54+
55+
**Output:** [{"val":{},"calls":1},{"val":{},"calls":1},{"val":{},"calls":1}]
56+
57+
**Explanation:** 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.
58+
59+
**Constraints:**
60+
61+
* <code>1 <= inputs.length <= 10<sup>5</sup></code>
62+
* <code>0 <= inputs.flat().length <= 10<sup>5</sup></code>
63+
* `inputs[i][j] != NaN`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// #Hard #2023_08_31_Time_264_ms_(98.86%)_Space_115.9_MB_(61.71%)
2+
3+
type Fn = (...params: any) => any
4+
5+
function memoize(fn: Fn): Fn {
6+
const cache = new Map();
7+
8+
return function(...args) {
9+
let currentCache;
10+
if (cache.has(args.length)) {
11+
currentCache = cache.get(args.length);
12+
}
13+
else {
14+
currentCache = new Map();
15+
cache.set(args.length, currentCache);
16+
}
17+
18+
for (let i=0, len=args.length; i<=len; i++){
19+
const arg = args[i];
20+
const isEnd = i >= len - 1;
21+
22+
if (currentCache.has(arg)) {
23+
if (isEnd) {
24+
return currentCache.get(arg);
25+
}
26+
else {
27+
currentCache = currentCache.get(arg);
28+
}
29+
}
30+
else if (isEnd) {
31+
break;
32+
} else {
33+
const newSubCache = new Map();
34+
35+
currentCache.set(arg, newSubCache);
36+
currentCache = newSubCache;
37+
}
38+
}
39+
40+
let value = fn(...args);
41+
42+
currentCache.set(args[args.length - 1], value);
43+
return value;
44+
}
45+
}
46+
47+
/*
48+
* let callCount = 0;
49+
* const memoizedFn = memoize(function (a, b) {
50+
* callCount += 1;
51+
* return a + b;
52+
* })
53+
* memoizedFn(2, 3) // 5
54+
* memoizedFn(2, 3) // 5
55+
* console.log(callCount) // 1
56+
*/
57+
58+
export { memoize }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
2631\. Group By
2+
3+
Medium
4+
5+
Write code that enhances all arrays such that you can call the `array.groupBy(fn)` method on any array and it will return a **grouped** version of the array.
6+
7+
A **grouped** array is an object where each key is the output of `fn(arr[i])` and each value is an array containing all items in the original array with that key.
8+
9+
The provided callback `fn` will accept an item in the array and return a string key.
10+
11+
The order of each value list should be the order the items appear in the array. Any order of keys is acceptable.
12+
13+
Please solve it without lodash's `_.groupBy` function.
14+
15+
**Example 1:**
16+
17+
**Input:**
18+
19+
array = [
20+
{"id":"1"},
21+
{"id":"1"},
22+
{"id":"2"}
23+
],
24+
fn = function (item) {
25+
return item.id;
26+
}
27+
28+
**Output:**
29+
30+
{
31+
"1": [{"id": "1"}, {"id": "1"}],
32+
"2": [{"id": "2"}]
33+
}
34+
35+
**Explanation:**
36+
37+
Output is from array.groupBy(fn).
38+
The selector function gets the "id" out of each item in the array.
39+
There are two objects with an "id" of 1. Both of those objects are put in the first array.
40+
There is one object with an "id" of 2. That object is put in the second array.
41+
42+
**Example 2:**
43+
44+
**Input:**
45+
46+
array = [
47+
[1, 2, 3],
48+
[1, 3, 5],
49+
[1, 5, 9]
50+
]
51+
fn = function (list) {
52+
return String(list[0]);
53+
}
54+
55+
**Output:**
56+
57+
{
58+
"1": [[1, 2, 3], [1, 3, 5], [1, 5, 9]]
59+
}
60+
61+
**Explanation:**
62+
63+
The array can be of any type. In this case, the selector function defines the key as being the first element in the array.
64+
65+
All the arrays have 1 as their first element so they are grouped together.
66+
67+
{
68+
"1": [[1, 2, 3], [1, 3, 5], [1, 5, 9]]
69+
}
70+
71+
**Example 3:**
72+
73+
**Input:**
74+
75+
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
76+
fn = function (n) {
77+
return String(n > 5);
78+
}
79+
80+
**Output:**
81+
82+
{
83+
"true": [6, 7, 8, 9, 10],
84+
"false": [1, 2, 3, 4, 5]
85+
}
86+
87+
**Explanation:** The selector function splits the array by whether each number is greater than 5.
88+
89+
**Constraints:**
90+
91+
* <code>0 <= array.length <= 10<sup>5</sup></code>
92+
* `fn returns a string`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// #Medium #2023_08_31_Time_101_ms_(99.50%)_Space_63.8_MB_(87.11%)
2+
3+
declare global {
4+
interface Array<T> {
5+
groupBy(fn: (item: T) => string): Record<string, T[]>
6+
}
7+
}
8+
9+
Array.prototype.groupBy = function<T>(fn: (item: T) => string) { //NOSONAR
10+
const returnObject: Record<string, T[]> = {};
11+
for (const item of this) {
12+
const key = fn(item);
13+
if (key in returnObject) {
14+
returnObject[key].push(item);
15+
} else {
16+
returnObject[key] = [item];
17+
}
18+
}
19+
return returnObject;
20+
};
21+
22+
/*
23+
* [1,2,3].groupBy(String) // {"1":[1],"2":[2],"3":[3]}
24+
*/
25+
26+
export { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2634\. Filter Elements from Array
2+
3+
Easy
4+
5+
Given an integer array `arr` and a filtering function `fn`, return a filtered array `filteredArr`.
6+
7+
The `fn` function takes one or two arguments:
8+
9+
* `arr[i]` - number from the `arr`
10+
* `i` - index of `arr[i]`
11+
12+
`filteredArr` should only contain the elements from the `arr` for which the expression `fn(arr[i], i)` evaluates to a **truthy** value. A **truthy** value is a value where `Boolean(value)` returns `true`.
13+
14+
Please solve it without the built-in Array.filter method.
15+
16+
**Example 1:**
17+
18+
**Input:** arr = [0,10,20,30], fn = function greaterThan10(n) { return n > 10; }
19+
20+
**Output:** [20,30]
21+
22+
**Explanation:**
23+
24+
const newArray = filter(arr, fn); // [20, 30]
25+
26+
The function filters out values that are not greater than 10
27+
28+
**Example 2:**
29+
30+
**Input:** arr = [1,2,3], fn = function firstIndex(n, i) { return i === 0; }
31+
32+
**Output:** [1]
33+
34+
**Explanation:**
35+
36+
fn can also accept the index of each element
37+
38+
In this case, the function removes elements not at index 0
39+
40+
**Example 3:**
41+
42+
**Input:** arr = [-2,-1,0,1,2], fn = function plusOne(n) { return n + 1 }
43+
44+
**Output:** [-2,0,1,2]
45+
46+
**Explanation:** Falsey values such as 0 should be filtered out
47+
48+
**Constraints:**
49+
50+
* `0 <= arr.length <= 1000`
51+
* <code>-10<sup>9</sup> <= arr[i] <= 10<sup>9</sup></code>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// #Easy #2023_08_31_Time_44_ms_(98.04%)_Space_42.7_MB_(69.67%)
2+
3+
function filter(arr: number[], fn: (n: number, i: number) => boolean): number[] {
4+
const filteredArr: number[] = []
5+
6+
for (let i = 0; i < arr.length; i++) {
7+
if (fn(arr[i], i)) filteredArr.push(arr[i])
8+
}
9+
10+
return filteredArr
11+
}
12+
13+
export { filter }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2635\. Apply Transform Over Each Element in Array
2+
3+
Easy
4+
5+
Given an integer array `arr` and a mapping function `fn`, return a new array with a transformation applied to each element.
6+
7+
The returned array should be created such that `returnedArray[i] = fn(arr[i], i)`.
8+
9+
Please solve it without the built-in `Array.map` method.
10+
11+
**Example 1:**
12+
13+
**Input:** arr = [1,2,3], fn = function plusone(n) { return n + 1; }
14+
15+
**Output:** [2,3,4]
16+
17+
**Explanation:**
18+
19+
const newArray = map(arr, plusone); // [2,3,4]
20+
21+
The function increases each value in the array by one.
22+
23+
**Example 2:**
24+
25+
**Input:** arr = [1,2,3], fn = function plusI(n, i) { return n + i; }
26+
27+
**Output:** [1,3,5]
28+
29+
**Explanation:** The function increases each value by the index it resides in.
30+
31+
**Example 3:**
32+
33+
**Input:** arr = [10,20,30], fn = function constant() { return 42; }
34+
35+
**Output:** [42,42,42]
36+
37+
**Explanation:** The function always returns 42.
38+
39+
**Constraints:**
40+
41+
* `0 <= arr.length <= 1000`
42+
* <code>-10<sup>9</sup> <= arr[i] <= 10<sup>9</sup></code>
43+
* `fn returns a number`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// #Easy #2023_08_31_Time_43_ms_(98.46%)_Space_42.2_MB_(92.83%)
2+
3+
function map(arr: number[], fn: (n: number, i: number) => number): number[] {
4+
const res: number[] = []
5+
for (let i = 0; i < arr.length; i++) {
6+
res.push(fn(arr[i], i))
7+
}
8+
return res
9+
}
10+
11+
export { map }

0 commit comments

Comments
 (0)