Skip to content

Commit

Permalink
Merge pull request #390 from sir-gon/feature/crush
Browse files Browse the repository at this point in the history
[Hacker Rank] Interview Preparation Kit: Arrays: Array Manipulation. …
  • Loading branch information
sir-gon authored Jul 18, 2024
2 parents 93bdc65 + 756522c commit e1e08fe
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 0 deletions.
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
}
]

0 comments on commit e1e08fe

Please sign in to comment.