Skip to content

Commit

Permalink
test(arrays): Add triplets finder
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Baquiax committed Jan 16, 2022
1 parent 208f8d8 commit ba69319
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 0 deletions.
100 changes: 100 additions & 0 deletions arrays/triplets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package arrays

import (
"sort"
)

// Given an array of distinct integers and a sum value.
// Find count of triplets with sum smaller than given sum value.
// Examples:

// Input : arr[] = {-2, 0, 1, 3}
// sum = 2.
// Output : 2
// Explanation : Below are triplets with sum less than 2
// (-2, 0, 1) and (-2, 0, 3)

// Input : arr[] = {5, 1, 3, 4, 7}
// sum = 12.
// Output : 4
// Explanation : Below are triplets with sum less than 12
// (1, 3, 4), (1, 3, 5), (1, 3, 7) and
// (1, 4, 5)

func findTriples(numbers []int, targetSum int) int {
// Brainstorm
// 1. We need to generate all the triplets and then sum up the values
// and the discarging those that sum up >= targetSum
//

if len(numbers) < 3 {
return 0
}

// step# 1: array: [5, 1, 3, 4, 7], target: 12
sort.Ints(numbers)

// step# 2: [1, 3, 4, 5, 7]
// firstIndex: 0, secondIndex: 1, thirdIndex: 2
// pair sum: 1 + 3 < 12 = true
// pair + third: 4 + 4 < 12 = true
// firstIndex: 0, secondIndex: 2, thirdIndex: 3
// triplets: 1
// pair sum: 1 + 4 < 12 = true
// pair + third: 5 + 5 < 12 true
// triplets: 2
// pair sum: 1 + 5 < 12 = true
// pair + third: 6 + 7 < 12 false
// paur sum: 3

lastIndex := len(numbers) - 1
tripletsCounter := 0
firstIndex := 0
secondIndex := 1
thirdIndex := 2

for {
if thirdIndex > lastIndex {
secondIndex++
thirdIndex = secondIndex + 1
}

if secondIndex > lastIndex-1 {
firstIndex++
secondIndex = firstIndex + 1
thirdIndex = secondIndex + 1
}

if firstIndex > lastIndex-2 {
break
}

firstNumber := numbers[firstIndex]
secondNumber := numbers[secondIndex]
thirdNumber := numbers[thirdIndex]

// base case: if in the ordered list we found in the left hand side
// a number greater or equals than the target number, it is not
// needed to continue iterating.
if firstNumber >= targetSum {
break
}

pairSum := firstNumber + secondNumber
if pairSum >= targetSum {
secondIndex++
thirdIndex = secondIndex + 1
continue
}

fullSum := pairSum + thirdNumber
thirdIndex++
if fullSum >= targetSum {
continue
}

tripletsCounter++
}

return tripletsCounter
}
62 changes: 62 additions & 0 deletions arrays/triplets_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package arrays

import (
"fmt"
"testing"
)

func TestFindTriples(t *testing.T) {
tests := []struct {
numbers []int
sumTarget int
want int
}{
{
numbers: []int{-2, 0, 1, 3},
sumTarget: 2,
want: 2,
},
{
numbers: []int{5, 1, 3, 4, 7},
sumTarget: 12,
want: 4,
},
{
numbers: []int{5, 6, 4, 3, 3},
sumTarget: 4,
want: 0,
},
{
numbers: []int{},
sumTarget: 4,
want: 0,
},
{
numbers: []int{1, 50, 13, 23, 40, 33, 3, 1},
sumTarget: 6,
want: 1,
},
}

for _, test := range tests {
t.Run(fmt.Sprintf("Should get %d When %v is given", test.want, test.numbers), func(t *testing.T) {
result := findTriples(test.numbers, test.sumTarget)

if result != test.want {
t.Fatalf("wanted %d but got %d", test.want, result)
}
})
}

}

func BenchmarkFindTriples(b *testing.B) {
var result int
for i := 0; i <= b.N; i++ {
result = findTriples([]int{1, 50, 13, 23, 40, 33, 15}, 91)
}

if result < 0 {
b.Fatal()
}
}

0 comments on commit ba69319

Please sign in to comment.