Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hacker Rank] Interview Preparation Kit: Arrays: Array Manipulation. … #390

Merged
merged 1 commit into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions docs/hackerrank/interview_preparation_kit/arrays/crush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# [Arrays: Array Manipulation](https://www.hackerrank.com/challenges/crush)

Perform m operations on an array and print the maximum of the values.

- Difficulty: ` #hard `
- Category: ` #ProblemSolvingIntermediate `

Starting with a 1-indexed array of zeros and a list of operations, for each
operation add a value to each the array element between two given indices,
inclusive. Once all operations have been performed, return the maximum
value in the array.

## Example

Queries are interpreted as follows:

```text
a b k
1 5 3
4 8 7
6 9 1
```

Add the values of between the indices and inclusive:

```text
index-> 1 2 3 4 5 6 7 8 9 10
[0,0,0, 0, 0,0,0,0,0, 0]
[3,3,3, 3, 3,0,0,0,0, 0]
[3,3,3,10,10,7,7,7,0, 0]
[3,3,3,10,10,8,8,8,1, 0]
```

The largest value is `10` after all operations are performed.

## Function Description

Complete the function arrayManipulation in the editor below.

arrayManipulation has the following parameters:

- `int n` - the number of elements in the array
- `int queries[q][3]` - a two dimensional array of queries where
each `queries[i]` contains three integers, `a`, `b`, and `k`.

## Returns

- int - the maximum value in the resultant array

## Input Format

The first line contains two space-separated integers `n` and `m`, the size of
the array and the number of operations.
Each of the next `m` lines contains three space-separated integers
`a`, `b` and `k`, the left index, right index and summand.

## Constraints

- $ 3 \leq n \leq 10^7 $
- $ 1 \leq m \leq 2*10^5 $
- $ 1 \leq a \leq b \leq n $
- $ 0 \leq k \leq 10^9 $

## Sample Input

```text
5 3
1 2 100
2 5 100
3 4 100
```

## Sample Output

```text
200
````

## Explanation

After the first update the list is `100 100 0 0 0`.
After the second update list is `100 200 100 100 100`.
After the third update list is `100 200 200 200 100`.

The maximum value is `200`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# [Array Manipulation](https://www.hackerrank.com/challenges/crush)

Perform m operations on an array and print the maximum of the values.

- Difficulty: ` #hard `
- Category: ` #ProblemSolvingIntermediate `

## Solution sources

### Brute force idea

The first solution attempt is based on the idea of going through:

> each row and then,
> > each sub-set of elements affected by the operation.

With this principle, the algorithm becomes O(N^2)

### Optimized

Reading about posible optimizations,
I found the possibility of summarizing the interior traversal with
addition operations for each element in each row of operations,
in only 2 constant operations, which represents the necessary values so that
in a single final traversal, the sum values can be obtained "by drag".
The algorithm is called "prefix sum."

Some sources about "prefix sum"

- <https://hmn.wiki/en/Prefix_sum>
- <https://en.wikipedia.org/wiki/Prefix_sum>
- <https://usaco.guide/silver/prefix-sums?lang=py>

Some sources about implementation in:

- [HackerRank Array Manipulation — beat the clock using Prefix Sum (JavaScript)](https://medium.com/@mlgerardvla/hackerrank-array-manipulation-beat-the-clock-using-prefix-sum-92471060035e)
- [Hackerrank Discussions Forums: Array Manipulation](https://www.hackerrank.com/challenges/one-month-preparation-kit-crush/forum)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { describe, expect, it } from '@jest/globals';
import { logger as console } from '../../../logger';

import { default as TEST_CASES } from './cruch_testcases_test.json';

import { arrayManipulation } from './cruch_bruteforce';

describe('arrays: crush (bruteforce) small cases', () => {
it('arrayManipulation Test Cases', () => {
expect.assertions(3);

TEST_CASES.forEach((test) => {
const answer = arrayManipulation(test.n, test.queries);

console.debug(
`rotLeftOne(${test.n}, ${test.queries}) solution found: ${answer}`
);

expect(answer).toStrictEqual(test.expected);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @link Problem definition [[docs/hackerrank/interview_preparation_kit/arrays/crush.md]]
* @see Solution Notes: [[docs/hackerrank/interview_preparation_kit/arrays/crush_optimized-solution-notes.md]]
*/

import { logger as console } from '../../../logger';

export function arrayManipulation(n: number, queries: number[][]): number {
const LENGTH = n + 1;
const SURROGATE_VALUE = 0;
const result = Array(LENGTH).fill(SURROGATE_VALUE);
let maximum = 0;

queries.forEach((query) => {
const [a_start, b_end, k_value] = query;
console.debug(`start -> ${result}`);

for (let i = a_start; i <= b_end; i++) {
result[i] += k_value;
console.debug(`result -> ${result}`);
}
});

result.forEach((value) => {
maximum = Math.max(value, maximum);
});

return maximum;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { describe, expect, it } from '@jest/globals';
import { logger as console } from '../../../logger';

import { default as TEST_CASES } from './cruch_testcases_test.json';

import { arrayManipulation } from './cruch_optimized';

describe('arrays: crush (optimized)', () => {
it('arrayManipulation Test Cases', () => {
expect.assertions(3);

TEST_CASES.forEach((test) => {
const answer = arrayManipulation(test.n, test.queries);

console.debug(
`rotLeftOne(${test.n}, ${test.queries}) solution found: ${answer}`
);

expect(answer).toStrictEqual(test.expected);
});
});
});
29 changes: 29 additions & 0 deletions src/hackerrank/interview_preparation_kit/arrays/cruch_optimized.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @link Problem definition [[docs/hackerrank/interview_preparation_kit/arrays/crush.md]]
*/

export function arrayManipulation(n: number, queries: number[][]): number {
// why adding 2?
// first slot to adjust 1-based index and
// last slot for storing accum_sum result
const LENGTH = n + 2;
const INITIAL_VALUE = 0;
const result = Array(LENGTH).fill(INITIAL_VALUE);
let maximum = 0;

queries.forEach((query) => {
const [a_start, b_end, k_value] = query;

result[a_start] += k_value;
result[b_end + 1] -= k_value;
});

let accum_sum = 0;

result.forEach((value) => {
accum_sum += value;
maximum = Math.max(maximum, accum_sum);
});

return maximum;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[
{
"title": "Sample Test Case 0",
"n": 5,
"queries": [
[
1,
2,
100
],
[
2,
5,
100
],
[
3,
4,
100
]
],
"expected": 200
},
{
"title": "Sample Test Case 1",
"n": 10,
"queries": [
[
1,
5,
3
],
[
4,
8,
7
],
[
6,
9,
1
]
],
"expected": 10
},
{
"title": "Sample Test Case 3",
"n": 10,
"queries": [
[
2,
6,
8
],
[
3,
5,
7
],
[
1,
8,
1
],
[
5,
9,
15
]
],
"expected": 31
}
]