Skip to content

Commit 02968fe

Browse files
authored
Merge pull request #314 from sir-gon/feature/crush
[Hacker Rank] Interview Preparation Kit: Arrays: Array Manipulation. …
2 parents 3c781a4 + bb49de1 commit 02968fe

File tree

7 files changed

+330
-0
lines changed

7 files changed

+330
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# [Arrays: Array Manipulation](https://www.hackerrank.com/challenges/crush)
2+
3+
Perform m operations on an array and print the maximum of the values.
4+
5+
- Difficulty: ` #hard `
6+
- Category: ` #ProblemSolvingIntermediate `
7+
8+
Starting with a 1-indexed array of zeros and a list of operations, for each
9+
operation add a value to each the array element between two given indices,
10+
inclusive. Once all operations have been performed, return the maximum
11+
value in the array.
12+
13+
## Example
14+
15+
Queries are interpreted as follows:
16+
17+
```text
18+
a b k
19+
1 5 3
20+
4 8 7
21+
6 9 1
22+
```
23+
24+
Add the values of between the indices and inclusive:
25+
26+
```text
27+
index-> 1 2 3 4 5 6 7 8 9 10
28+
[0,0,0, 0, 0,0,0,0,0, 0]
29+
[3,3,3, 3, 3,0,0,0,0, 0]
30+
[3,3,3,10,10,7,7,7,0, 0]
31+
[3,3,3,10,10,8,8,8,1, 0]
32+
```
33+
34+
The largest value is `10` after all operations are performed.
35+
36+
## Function Description
37+
38+
Complete the function arrayManipulation in the editor below.
39+
40+
arrayManipulation has the following parameters:
41+
42+
- `int n` - the number of elements in the array
43+
- `int queries[q][3]` - a two dimensional array of queries where
44+
each `queries[i]` contains three integers, `a`, `b`, and `k`.
45+
46+
## Returns
47+
48+
- int - the maximum value in the resultant array
49+
50+
## Input Format
51+
52+
The first line contains two space-separated integers `n` and `m`, the size of
53+
the array and the number of operations.
54+
Each of the next `m` lines contains three space-separated integers
55+
`a`, `b` and `k`, the left index, right index and summand.
56+
57+
## Constraints
58+
59+
- $3 \leq n \leq 10^7$
60+
- $1 \leq m \leq 2*10^5$
61+
- $1 \leq a \leq b \leq n$
62+
- $0 \leq k \leq 10^9$
63+
64+
## Sample Input
65+
66+
```text
67+
5 3
68+
1 2 100
69+
2 5 100
70+
3 4 100
71+
```
72+
73+
## Sample Output
74+
75+
```text
76+
200
77+
````
78+
79+
## Explanation
80+
81+
After the first update the list is `100 100 0 0 0`.
82+
After the second update list is `100 200 100 100 100`.
83+
After the third update list is `100 200 200 200 100`.
84+
85+
The maximum value is `200`.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# [Array Manipulation](https://www.hackerrank.com/challenges/crush)
2+
3+
Perform m operations on an array and print the maximum of the values.
4+
5+
- Difficulty: ` #hard `
6+
- Category: ` #ProblemSolvingIntermediate `
7+
8+
## Solution sources
9+
10+
### Brute force idea
11+
12+
The first solution attempt is based on the idea of going through:
13+
14+
> each row and then,
15+
> > each sub-set of elements affected by the operation.
16+
17+
With this principle, the algorithm becomes O(N^2)
18+
19+
### Optimized
20+
21+
Reading about posible optimizations,
22+
I found the possibility of summarizing the interior traversal with
23+
addition operations for each element in each row of operations,
24+
in only 2 constant operations, which represents the necessary values so that
25+
in a single final traversal, the sum values can be obtained "by drag".
26+
The algorithm is called "prefix sum."
27+
28+
Some sources about "prefix sum"
29+
30+
- <https://hmn.wiki/en/Prefix_sum>
31+
- <https://en.wikipedia.org/wiki/Prefix_sum>
32+
- <https://usaco.guide/silver/prefix-sums?lang=py>
33+
34+
Some sources about implementation in:
35+
36+
- [HackerRank Array Manipulation — beat the clock using Prefix Sum (JavaScript)](https://medium.com/@mlgerardvla/hackerrank-array-manipulation-beat-the-clock-using-prefix-sum-92471060035e)
37+
- [Hackerrank Discussions Forums: Array Manipulation](https://www.hackerrank.com/challenges/one-month-preparation-kit-crush/forum)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @link Problem definition [[docs/hackerrank/interview_preparation_kit/2d_array.md]]
3+
*/
4+
5+
package hackerrank
6+
7+
func arrayManipulation(n int32, queries [][]int32) int64 {
8+
// why adding 2?
9+
// first slot to adjust 1-based index and
10+
// last slot for storing accumSum result
11+
var LENGTH int32 = n + 2
12+
const InitialValue int64 = 0
13+
var maximum int64 = 0
14+
15+
result := make([]int64, LENGTH)
16+
for i := 0; int32(i) < LENGTH; i++ {
17+
result[i] = InitialValue
18+
}
19+
20+
var aStart int32
21+
var bEnd int32
22+
var kValue int32
23+
24+
for _, query_row := range queries {
25+
aStart = query_row[0]
26+
bEnd = query_row[1]
27+
kValue = query_row[2]
28+
29+
result[aStart] += int64(kValue)
30+
result[bEnd+1] -= int64(kValue)
31+
}
32+
33+
var accumSum int64 = 0
34+
35+
for _, value := range result {
36+
accumSum += value
37+
if accumSum > maximum {
38+
maximum = accumSum
39+
}
40+
}
41+
42+
return maximum
43+
}
44+
45+
func ArrayManipulation(n int32, queries [][]int32) int64 {
46+
return arrayManipulation(n, queries)
47+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[
2+
{
3+
"title": "Sample Test Case 0",
4+
"n": 5,
5+
"queries": [
6+
[1, 2, 100],
7+
[2, 5, 100],
8+
[3, 4, 100]
9+
],
10+
"expected": 200
11+
},
12+
{
13+
"title": "Sample Test Case 1",
14+
"n": 10,
15+
"queries": [
16+
[1, 5, 3],
17+
[4, 8, 7],
18+
[6, 9, 1]
19+
],
20+
"expected": 10
21+
},
22+
{
23+
"title": "Sample Test Case 3",
24+
"n": 10,
25+
"queries": [
26+
[2, 6, 8],
27+
[3, 5, 7],
28+
[1, 8, 1],
29+
[5, 9, 15]
30+
],
31+
"expected": 31
32+
}
33+
]
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @link Problem definition [[docs/hackerrank/interview_preparation_kit/arrays/crush.md]]
3+
*/
4+
5+
package hackerrank
6+
7+
import "slices"
8+
9+
func arrayManipulationBruteForce(n int32, queries [][]int32) int64 {
10+
var LENGTH int32 = n + 1
11+
const InitialValue int64 = 0
12+
13+
result := make([]int64, LENGTH)
14+
for i := 0; int32(i) < LENGTH; i++ {
15+
result[i] = InitialValue
16+
}
17+
18+
var aStart int32
19+
var bEnd int32
20+
var kValue int32
21+
22+
for _, query_row := range queries {
23+
aStart = query_row[0]
24+
bEnd = query_row[1]
25+
kValue = query_row[2]
26+
27+
for i := aStart; i <= bEnd; i++ {
28+
result[i] += int64(kValue)
29+
}
30+
}
31+
32+
return int64(slices.Max(result))
33+
34+
}
35+
36+
func ArrayManipulationBruteForce(n int32, queries [][]int32) int64 {
37+
return arrayManipulationBruteForce(n, queries)
38+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package hackerrank
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
"gon.cl/algorithms/utils"
10+
)
11+
12+
type CrushBruteForceTestCase struct {
13+
N int32 `json:"n"`
14+
Queries [][]int32 `json:"queries"`
15+
Expected int64 `json:"expected"`
16+
}
17+
18+
var CrushBruteForceTestCases []CrushBruteForceTestCase
19+
20+
// You can use testing.T, if you want to test the code without benchmarking
21+
func CrushBruteForceSetupSuite(t testing.TB) {
22+
wd, _ := os.Getwd()
23+
filepath := wd + "/crush.testcases.json"
24+
t.Log("Setup test cases from JSON: ", filepath)
25+
26+
var _, err = utils.LoadJSON(filepath, &CrushBruteForceTestCases)
27+
if err != nil {
28+
t.Log(err)
29+
}
30+
}
31+
32+
func TestCrushBruteForce(t *testing.T) {
33+
34+
CrushBruteForceSetupSuite(t)
35+
36+
for _, tt := range CrushBruteForceTestCases {
37+
testname := fmt.Sprintf("ArrayManipulationBruteForce(%d, %v) => %d \n", tt.N, tt.Queries, tt.Expected)
38+
t.Run(testname, func(t *testing.T) {
39+
40+
ans := ArrayManipulationBruteForce(tt.N, tt.Queries)
41+
assert.Equal(t, tt.Expected, ans)
42+
})
43+
44+
}
45+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package hackerrank
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
"gon.cl/algorithms/utils"
10+
)
11+
12+
type CrushTestCase struct {
13+
N int32 `json:"n"`
14+
Queries [][]int32 `json:"queries"`
15+
Expected int64 `json:"expected"`
16+
}
17+
18+
var CrushTestCases []CrushTestCase
19+
20+
// You can use testing.T, if you want to test the code without benchmarking
21+
func CrushSetupSuite(t testing.TB) {
22+
wd, _ := os.Getwd()
23+
filepath := wd + "/crush.testcases.json"
24+
t.Log("Setup test cases from JSON: ", filepath)
25+
26+
var _, err = utils.LoadJSON(filepath, &CrushTestCases)
27+
if err != nil {
28+
t.Log(err)
29+
}
30+
}
31+
32+
func TestCrush(t *testing.T) {
33+
34+
CrushSetupSuite(t)
35+
36+
for _, tt := range CrushTestCases {
37+
testname := fmt.Sprintf("ArrayManipulation(%d, %v) => %d \n", tt.N, tt.Queries, tt.Expected)
38+
t.Run(testname, func(t *testing.T) {
39+
40+
ans := ArrayManipulation(tt.N, tt.Queries)
41+
assert.Equal(t, tt.Expected, ans)
42+
})
43+
44+
}
45+
}

0 commit comments

Comments
 (0)