Skip to content

Commit 4435d6d

Browse files
authored
Merge pull request #332 from sir-gon/feature/count_triplets_1
[Hacker Rank] Interview Preparation Kit: Dictionaries and Hashmaps: C…
2 parents 73909bb + 814d32b commit 4435d6d

File tree

6 files changed

+289
-0
lines changed

6 files changed

+289
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# [Dictionaries and Hashmaps: Count Triplets](https://www.hackerrank.com/challenges/count-triplets-1)
2+
3+
- Difficulty: `#medium`
4+
- Category: `#ProblemSolvingIntermediate`
5+
6+
## Working solution
7+
8+
This solution in O(N), is based on considering that each
9+
number analyzed is in the center of the triplet and asks
10+
"how many" possible cases there are on the left and
11+
right to calculate how many possible triplets are formed.
12+
13+
- Source: [Hackerrank - Count Triplets Solution](https://www.thepoorcoder.com/hackerrank-count-triplets-solution/)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# [Dictionaries and Hashmaps: Count Triplets](https://www.hackerrank.com/challenges/count-triplets-1)
2+
3+
- Difficulty: `#medium`
4+
- Category: `#ProblemSolvingIntermediate` `#dictionaries` `#hashmaps`
5+
6+
You are given an array and you need to find number of
7+
tripets of indices (i, j, k) such that the elements at
8+
those indices are in geometric progression for a given
9+
common ratio `r` and $ i < j < k $.
10+
11+
## Example
12+
13+
`arr = [1, 4, 16, 64] r = 4`
14+
15+
There are `[1, 4, 16]` and `[4, 16, 64]` at indices (0, 1, 2) and (1, 2, 3).
16+
Return `2`.
17+
18+
## Function Description
19+
20+
Complete the countTriplets function in the editor below.
21+
22+
countTriplets has the following parameter(s):
23+
24+
- `int arr[n]`: an array of integers
25+
- `int r`: the common ratio
26+
27+
## Returns
28+
29+
- `int`: the number of triplets
30+
31+
## Input Format
32+
33+
The first line contains two space-separated integers `n` and `r`,
34+
the size of `arr` and the common ratio.
35+
The next line contains `n` space-seperated integers `arr[i]`.
36+
37+
## Constraints
38+
39+
- $ 1 \leq n \leq 10^5 $
40+
- $ 1 \leq r \leq 10^9 $
41+
- $ 1 \leq arr[i] \leq 10^9 $
42+
43+
## Sample Input 0
44+
45+
```text
46+
4 2
47+
1 2 2 4
48+
```
49+
50+
## Sample Output 0
51+
52+
```text
53+
2
54+
```
55+
56+
## Explanation 0
57+
58+
There are `2` triplets in satisfying our criteria,
59+
whose indices are (0, 1, 3) and (0, 2, 3)
60+
61+
## Sample Input 1
62+
63+
```text
64+
6 3
65+
1 3 9 9 27 81
66+
```
67+
68+
## Sample Output 1
69+
70+
```text
71+
6
72+
```
73+
74+
## Explanation 1
75+
76+
The triplets satisfying are index
77+
`(0, 1, 2)`, `(0, 1, 3)`, `(1, 2, 4)`, `(1, 3, 4)`, `(2, 4, 5)` and `(3, 4, 5)`.
78+
79+
## Sample Input 2
80+
81+
```text
82+
5 5
83+
1 5 5 25 125
84+
```
85+
86+
## Sample Output 2
87+
88+
```text
89+
4
90+
```
91+
92+
## Explanation 2
93+
94+
The triplets satisfying are index
95+
`(0, 1, 3)`, `(0, 2, 3)`, `(1, 2, 3)`, `(2, 3, 4)`.
96+
97+
## Appendix
98+
99+
[Solution notes](count_triplets_1-solution-notes.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
{
3+
"title": "Sample Test Case 2",
4+
"input": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
7+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
8+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
9+
"r": 1,
10+
"expected": 161700
11+
}
12+
]
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* @link Problem definition [[docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/count_triplets_1.md]]
3+
*/
4+
5+
package hackerrank
6+
7+
func countTripletsBruteForce(arr []int64, r int64) int64 {
8+
size := len(arr)
9+
counter := int64(0)
10+
for i := 0; i < size-2; i++ {
11+
for j := i + 1; j < size-1; j++ {
12+
for k := j + 1; k < size; k++ {
13+
if r*arr[i] == arr[j] && r*arr[j] == arr[k] {
14+
counter++
15+
}
16+
}
17+
}
18+
}
19+
return counter
20+
}
21+
22+
func countTriplets(arr []int64, r int64) int64 {
23+
aCounter := make(map[int64]int64)
24+
bCounter := make(map[int64]int64)
25+
triplets := int64(0)
26+
27+
for _, item := range arr {
28+
if _, ok := aCounter[item]; ok && aCounter[item] > 0 {
29+
aCounter[item] += 1
30+
} else {
31+
aCounter[item] = 1
32+
}
33+
}
34+
35+
for _, item := range arr {
36+
j := item / r
37+
k := item * r
38+
39+
aCounter[item]--
40+
if bCounter[j] > 0 && aCounter[k] > 0 && item%r == 0 {
41+
triplets += bCounter[j] * aCounter[k]
42+
}
43+
bCounter[item]++
44+
}
45+
46+
return triplets
47+
}
48+
49+
func CountTriplets(arr []int64, r int64) int64 {
50+
return countTriplets(arr, r)
51+
}
52+
53+
func CountTripletsBruteForce(arr []int64, r int64) int64 {
54+
return countTripletsBruteForce(arr, r)
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[
2+
{
3+
"title": "Sample Test Case 0",
4+
"input": [1, 2, 2, 4],
5+
"r": 2,
6+
"expected": 2
7+
},
8+
{
9+
"title": "Sample Test Case 1",
10+
"input": [1, 3, 9, 9, 27, 81],
11+
"r": 3,
12+
"expected": 6
13+
},
14+
{
15+
"title": "Sample Test Case 1 (unsorted)",
16+
"input": [9, 3, 1, 81, 9, 27],
17+
"r": 3,
18+
"expected": 1
19+
},
20+
{
21+
"title": "Sample Test Case 12",
22+
"input": [1, 5, 5, 25, 125],
23+
"r": 5,
24+
"expected": 4
25+
}
26+
]
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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 CountTripletsTestCase struct {
13+
Input []int64 `json:"Input"`
14+
Ratio int64 `json:"r"`
15+
Expected int64 `json:"expected"`
16+
}
17+
18+
var CountTripletsTestCases []CountTripletsTestCase
19+
var CountTripletsBigTestCases []CountTripletsTestCase
20+
21+
// You can use testing.T, if you want to test the code without benchmarking
22+
func CountTripletsSetupSuite(t testing.TB) {
23+
wd, _ := os.Getwd()
24+
filepath := wd + "/count-triplets-1.small.testcases.json"
25+
t.Log("Setup test cases from JSON: ", filepath)
26+
27+
var _, err = utils.LoadJSON(filepath, &CountTripletsTestCases)
28+
if err != nil {
29+
t.Log(err)
30+
}
31+
}
32+
33+
func CountTripletsSetupSuiteBigCases(t testing.TB) {
34+
wd, _ := os.Getwd()
35+
filepath := wd + "/count-triplets-1.big.testcases.json"
36+
t.Log("Setup test cases from JSON: ", filepath)
37+
38+
var _, err = utils.LoadJSON(filepath, &CountTripletsBigTestCases)
39+
if err != nil {
40+
t.Log(err)
41+
}
42+
}
43+
44+
func TestCountTriplets(t *testing.T) {
45+
46+
CountTripletsSetupSuite(t)
47+
48+
for _, tt := range CountTripletsTestCases {
49+
testname := fmt.Sprintf("CountTriplets(%v, %v) => %v \n", tt.Input, tt.Ratio, tt.Expected)
50+
t.Run(testname, func(t *testing.T) {
51+
ans := CountTriplets(tt.Input, tt.Ratio)
52+
assert.Equal(t, tt.Expected, ans)
53+
})
54+
55+
}
56+
}
57+
58+
func TestCountTripletsBigCases(t *testing.T) {
59+
60+
CountTripletsSetupSuiteBigCases(t)
61+
62+
for _, tt := range CountTripletsBigTestCases {
63+
testname := fmt.Sprintf("CountTriplets(%v, %v) => %v \n", tt.Input, tt.Ratio, tt.Expected)
64+
t.Run(testname, func(t *testing.T) {
65+
ans := CountTriplets(tt.Input, tt.Ratio)
66+
assert.Equal(t, tt.Expected, ans)
67+
})
68+
69+
}
70+
}
71+
72+
func TestCountTripletsBruteForce(t *testing.T) {
73+
74+
CountTripletsSetupSuiteBigCases(t)
75+
76+
for _, tt := range CountTripletsTestCases {
77+
testname := fmt.Sprintf("CountTripletsBruteForce(%v, %v) => %v \n", tt.Input, tt.Ratio, tt.Expected)
78+
t.Run(testname, func(t *testing.T) {
79+
ans := CountTripletsBruteForce(tt.Input, tt.Ratio)
80+
assert.Equal(t, tt.Expected, ans)
81+
})
82+
83+
}
84+
}

0 commit comments

Comments
 (0)