updated util packages

This commit is contained in:
alexchao26
2020-12-10 01:04:51 -05:00
parent b9a74cf122
commit 1fec4f74d3
47 changed files with 285 additions and 95 deletions
+34
View File
@@ -0,0 +1,34 @@
package algos
// MakePermutations will make all permutations of the numbers input
// returns a pointer to avoid copying a large number of permutations
func MakePermutations(numbers []int) *[][]int {
result := make([][]int, 0)
swapRecurseBacktrack(numbers, 0, &result)
return &result
}
// helper function to generate permutations
func swapRecurseBacktrack(numbers []int, startIndex int, results *[][]int) {
if startIndex == len(numbers) {
// make a copy of the perm
perm := make([]int, len(numbers))
copy(perm, numbers)
// assign the value at the pointer results to the appended slice (dereferenced) results w/ perm
*results = append(*results, perm)
}
for i := startIndex; i < len(numbers); i++ {
// swap numbers
numbers[startIndex], numbers[i] = numbers[i], numbers[startIndex]
// recurse with startIndex incremented
swapRecurseBacktrack(numbers, startIndex+1, results)
// backtrack
numbers[startIndex], numbers[i] = numbers[i], numbers[startIndex]
}
}
+32
View File
@@ -0,0 +1,32 @@
package algos
// RotateGrid returns the inputted grid, rotated counterclockwise
// call it multiple times for 180, & 270 degree rotations
func RotateStringGrid(grid [][]string) [][]string {
rotated := make([][]string, len(grid[0]))
for i := range rotated {
rotated[i] = make([]string, len(grid))
}
for i := 0; i < len(grid); i++ {
for j := 0; j < len(grid[0]); j++ {
rotated[len(grid[0])-1-j][i] = grid[i][j]
}
}
return rotated
}
// RotateGridInts will transpose a 2D array of ints
func RotateIntGrid(grid [][]int) [][]int {
rotated := make([][]int, len(grid[0]))
for i := range rotated {
rotated[i] = make([]int, len(grid))
}
for i := 0; i < len(grid); i++ {
for j := 0; j < len(grid[0]); j++ {
rotated[len(grid[0])-1-j][i] = grid[i][j]
}
}
return rotated
}
+25
View File
@@ -0,0 +1,25 @@
package algos
// SlidingWindowSum returns the left and right indices of a window within the
// nums slice, where all numbers in the slice [left:right] sum up to targetSum
// It also returns a boolean indicating if a valid window is found
func SlidingWindowSum(nums []int, targetSum int) (leftIndex, rightIndex int, found bool) {
var left, right, sum int
for right < len(nums) {
switch {
case left == right:
sum += nums[right]
right++
case sum > targetSum:
sum -= nums[left]
left++
case sum < targetSum:
sum += nums[right]
right++
}
if sum == targetSum {
return left, right, true
}
}
return 0, 0, false
}
+36
View File
@@ -0,0 +1,36 @@
package algos
import "testing"
func TestSlidingWindowSum(t *testing.T) {
type args struct {
nums []int
targetSum int
}
tests := []struct {
name string
args args
wantLeftIndex int
wantRightIndex int
wantFound bool
}{
{"found 1", args{[]int{-1, 23, 12, 14, 3, 4}, 21}, 3, 6, true},
{"found 2", args{[]int{-1, 23, 12, 14, 3, 4, 59}, 21}, 3, 6, true},
{"not found 1", args{[]int{0, 1, 2, 3, 4, 5, 6}, 45}, 0, 0, false},
{"not found 2", args{[]int{0, 1, 2, 3, 4, 5, 6}, -34}, 0, 0, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotLeftIndex, gotRightIndex, gotFound := SlidingWindowSum(tt.args.nums, tt.args.targetSum)
if gotLeftIndex != tt.wantLeftIndex {
t.Errorf("SlidingWindowSum() gotLeftIndex = %v, want %v", gotLeftIndex, tt.wantLeftIndex)
}
if gotRightIndex != tt.wantRightIndex {
t.Errorf("SlidingWindowSum() gotRightIndex = %v, want %v", gotRightIndex, tt.wantRightIndex)
}
if gotFound != tt.wantFound {
t.Errorf("SlidingWindowSum() gotFound = %v, want %v", gotFound, tt.wantFound)
}
})
}
}
+27
View File
@@ -0,0 +1,27 @@
package algos
// TwoSum returns the two numbers found within a slice that add up to
// the input target, and a boolean to check if the sum is found or not
func TwoSum(nums []int, target int) (num1 int, num2 int, found bool) {
seen := make(map[int]bool, len(nums))
for _, v := range nums {
if seen[target-v] {
return target - v, v, true
}
seen[v] = true
}
return 0, 0, false
}
// ThreeSum returns the three values within a slice that sum to the
// target input and a boolean stating if a match was found
func ThreeSum(nums []int, target int) (int, int, int, bool) {
for i, v := range nums {
if num1, num2, found := TwoSum(nums[i+1:], target-v); found {
return v, num1, num2, true
}
}
return 0, 0, 0, false
}
+76
View File
@@ -0,0 +1,76 @@
package algos
import "testing"
func TestTwoSum(t *testing.T) {
type args struct {
nums []int
target int
}
tests := []struct {
name string
args args
wantNum1 int
wantNum2 int
wantFound bool
}{
{"found 1", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 6}, 2, 4, true},
{"found 2", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 17}, 8, 9, true},
{"not found 1", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 62}, 0, 0, false},
{"not found 2", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, -12}, 0, 0, false},
{"found 3", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -13}, -12}, 1, -13, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotNum1, gotNum2, gotFound := TwoSum(tt.args.nums, tt.args.target)
if gotNum1 != tt.wantNum1 {
t.Errorf("TwoSum() gotNum1 = %v, want %v", gotNum1, tt.wantNum1)
}
if gotNum2 != tt.wantNum2 {
t.Errorf("TwoSum() gotNum2 = %v, want %v", gotNum2, tt.wantNum2)
}
if gotFound != tt.wantFound {
t.Errorf("TwoSum() gotFound = %v, want %v", gotFound, tt.wantFound)
}
})
}
}
func TestThreeSum(t *testing.T) {
type args struct {
nums []int
target int
}
tests := []struct {
name string
args args
want int
want1 int
want2 int
want3 bool
}{
{"found 1", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 6}, 0, 2, 4, true},
{"found 2", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 17}, 0, 8, 9, true},
{"not found 1", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 62}, 0, 0, 0, false},
{"not found 2", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, -12}, 0, 0, 0, false},
{"found 3", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -13}, -12}, 0, 1, -13, true},
{"found 3", args{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 27}, 8, 9, 10, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1, got2, got3 := ThreeSum(tt.args.nums, tt.args.target)
if got != tt.want {
t.Errorf("ThreeSum() got = %v, want %v", got, tt.want)
}
if got1 != tt.want1 {
t.Errorf("ThreeSum() got1 = %v, want %v", got1, tt.want1)
}
if got2 != tt.want2 {
t.Errorf("ThreeSum() got2 = %v, want %v", got2, tt.want2)
}
if got3 != tt.want3 {
t.Errorf("ThreeSum() got3 = %v, want %v", got3, tt.want3)
}
})
}
}