From 92b1b8deeba4ebacf1bf6b29e623aa57c7c49f20 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Wed, 19 Mar 2025 12:21:07 -0300 Subject: [PATCH 1/2] [Hacker Rank] Interview Preparation Kit: Arrays: Array Manipulation. Initial (brute force) solution... --- .../interview_preparation_kit/arrays/crush.md | 85 +++++++++++++++++++ .../arrays/crush.testcases.json | 33 +++++++ .../arrays/crush_bruteforce.go | 38 +++++++++ .../arrays/crush_bruteforce_test.go | 45 ++++++++++ 4 files changed, 201 insertions(+) create mode 100644 docs/hackerrank/interview_preparation_kit/arrays/crush.md create mode 100644 exercises/hackerrank/interview_preparation_kit/arrays/crush.testcases.json create mode 100644 exercises/hackerrank/interview_preparation_kit/arrays/crush_bruteforce.go create mode 100644 exercises/hackerrank/interview_preparation_kit/arrays/crush_bruteforce_test.go diff --git a/docs/hackerrank/interview_preparation_kit/arrays/crush.md b/docs/hackerrank/interview_preparation_kit/arrays/crush.md new file mode 100644 index 0000000..9e8d29f --- /dev/null +++ b/docs/hackerrank/interview_preparation_kit/arrays/crush.md @@ -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`. diff --git a/exercises/hackerrank/interview_preparation_kit/arrays/crush.testcases.json b/exercises/hackerrank/interview_preparation_kit/arrays/crush.testcases.json new file mode 100644 index 0000000..fa4f8a1 --- /dev/null +++ b/exercises/hackerrank/interview_preparation_kit/arrays/crush.testcases.json @@ -0,0 +1,33 @@ +[ + { + "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 + } +] diff --git a/exercises/hackerrank/interview_preparation_kit/arrays/crush_bruteforce.go b/exercises/hackerrank/interview_preparation_kit/arrays/crush_bruteforce.go new file mode 100644 index 0000000..b36a0f4 --- /dev/null +++ b/exercises/hackerrank/interview_preparation_kit/arrays/crush_bruteforce.go @@ -0,0 +1,38 @@ +/** + * @link Problem definition [[docs/hackerrank/interview_preparation_kit/arrays/crush.md]] + */ + +package hackerrank + +import "slices" + +func arrayManipulationBruteForce(n int32, queries [][]int32) int64 { + var LENGTH int32 = n + 1 + const InitialValue int64 = 0 + + result := make([]int64, LENGTH) + for i := 0; int32(i) < LENGTH; i++ { + result[i] = InitialValue + } + + var aStart int32 + var bEnd int32 + var kValue int32 + + for _, query_row := range queries { + aStart = query_row[0] + bEnd = query_row[1] + kValue = query_row[2] + + for i := aStart; i <= bEnd; i++ { + result[i] += int64(kValue) + } + } + + return int64(slices.Max(result)) + +} + +func ArrayManipulationBruteForce(n int32, queries [][]int32) int64 { + return arrayManipulationBruteForce(n, queries) +} diff --git a/exercises/hackerrank/interview_preparation_kit/arrays/crush_bruteforce_test.go b/exercises/hackerrank/interview_preparation_kit/arrays/crush_bruteforce_test.go new file mode 100644 index 0000000..6bb5a8d --- /dev/null +++ b/exercises/hackerrank/interview_preparation_kit/arrays/crush_bruteforce_test.go @@ -0,0 +1,45 @@ +package hackerrank + +import ( + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "gon.cl/algorithms/utils" +) + +type CrushBruteForceTestCase struct { + N int32 `json:"n"` + Queries [][]int32 `json:"queries"` + Expected int64 `json:"expected"` +} + +var CrushBruteForceTestCases []CrushBruteForceTestCase + +// You can use testing.T, if you want to test the code without benchmarking +func CrushBruteForceSetupSuite(t testing.TB) { + wd, _ := os.Getwd() + filepath := wd + "/crush.testcases.json" + t.Log("Setup test cases from JSON: ", filepath) + + var _, err = utils.LoadJSON(filepath, &CrushBruteForceTestCases) + if err != nil { + t.Log(err) + } +} + +func TestCrushBruteForce(t *testing.T) { + + CrushBruteForceSetupSuite(t) + + for _, tt := range CrushBruteForceTestCases { + testname := fmt.Sprintf("ArrayManipulationBruteForce(%d, %v) => %d \n", tt.N, tt.Queries, tt.Expected) + t.Run(testname, func(t *testing.T) { + + ans := ArrayManipulationBruteForce(tt.N, tt.Queries) + assert.Equal(t, tt.Expected, ans) + }) + + } +} From bb49de15967a12f399cb6b0aa2d45dd54ef00e81 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Wed, 19 Mar 2025 15:01:48 -0300 Subject: [PATCH 2/2] =?UTF-8?q?[Hacker=20Rank]=20Interview=20Preparation?= =?UTF-8?q?=20Kit:=20Arrays:=20Array=20Manipulation.=20Solved=20=E2=9C=85.?= =?UTF-8?q?=20Optimized=20solution.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../arrays/crush_optimized-solution-notes.md | 37 +++++++++++++++ .../interview_preparation_kit/arrays/crush.go | 47 +++++++++++++++++++ .../arrays/crush_test.go | 45 ++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 docs/hackerrank/interview_preparation_kit/arrays/crush_optimized-solution-notes.md create mode 100644 exercises/hackerrank/interview_preparation_kit/arrays/crush.go create mode 100644 exercises/hackerrank/interview_preparation_kit/arrays/crush_test.go diff --git a/docs/hackerrank/interview_preparation_kit/arrays/crush_optimized-solution-notes.md b/docs/hackerrank/interview_preparation_kit/arrays/crush_optimized-solution-notes.md new file mode 100644 index 0000000..c22f0d9 --- /dev/null +++ b/docs/hackerrank/interview_preparation_kit/arrays/crush_optimized-solution-notes.md @@ -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" + +- +- +- + +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) diff --git a/exercises/hackerrank/interview_preparation_kit/arrays/crush.go b/exercises/hackerrank/interview_preparation_kit/arrays/crush.go new file mode 100644 index 0000000..2064d0c --- /dev/null +++ b/exercises/hackerrank/interview_preparation_kit/arrays/crush.go @@ -0,0 +1,47 @@ +/** + * @link Problem definition [[docs/hackerrank/interview_preparation_kit/2d_array.md]] + */ + +package hackerrank + +func arrayManipulation(n int32, queries [][]int32) int64 { + // why adding 2? + // first slot to adjust 1-based index and + // last slot for storing accumSum result + var LENGTH int32 = n + 2 + const InitialValue int64 = 0 + var maximum int64 = 0 + + result := make([]int64, LENGTH) + for i := 0; int32(i) < LENGTH; i++ { + result[i] = InitialValue + } + + var aStart int32 + var bEnd int32 + var kValue int32 + + for _, query_row := range queries { + aStart = query_row[0] + bEnd = query_row[1] + kValue = query_row[2] + + result[aStart] += int64(kValue) + result[bEnd+1] -= int64(kValue) + } + + var accumSum int64 = 0 + + for _, value := range result { + accumSum += value + if accumSum > maximum { + maximum = accumSum + } + } + + return maximum +} + +func ArrayManipulation(n int32, queries [][]int32) int64 { + return arrayManipulation(n, queries) +} diff --git a/exercises/hackerrank/interview_preparation_kit/arrays/crush_test.go b/exercises/hackerrank/interview_preparation_kit/arrays/crush_test.go new file mode 100644 index 0000000..10c032a --- /dev/null +++ b/exercises/hackerrank/interview_preparation_kit/arrays/crush_test.go @@ -0,0 +1,45 @@ +package hackerrank + +import ( + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "gon.cl/algorithms/utils" +) + +type CrushTestCase struct { + N int32 `json:"n"` + Queries [][]int32 `json:"queries"` + Expected int64 `json:"expected"` +} + +var CrushTestCases []CrushTestCase + +// You can use testing.T, if you want to test the code without benchmarking +func CrushSetupSuite(t testing.TB) { + wd, _ := os.Getwd() + filepath := wd + "/crush.testcases.json" + t.Log("Setup test cases from JSON: ", filepath) + + var _, err = utils.LoadJSON(filepath, &CrushTestCases) + if err != nil { + t.Log(err) + } +} + +func TestCrush(t *testing.T) { + + CrushSetupSuite(t) + + for _, tt := range CrushTestCases { + testname := fmt.Sprintf("ArrayManipulation(%d, %v) => %d \n", tt.N, tt.Queries, tt.Expected) + t.Run(testname, func(t *testing.T) { + + ans := ArrayManipulation(tt.N, tt.Queries) + assert.Equal(t, tt.Expected, ans) + }) + + } +}