Skip to content

Commit

Permalink
Merge pull request #6 from vaskoz/day4
Browse files Browse the repository at this point in the history
day 4 solution
  • Loading branch information
vaskoz committed Aug 25, 2018
2 parents eef67af + 121398e commit 551f318
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
56 changes: 56 additions & 0 deletions day4/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package day4

// PartitionBySign groups the negative values first, then zero values,
// then positive values.
// This operation happens in-place on the provided IntSlice.
//
// Returns the index to the first positive number.
// Runs in O(N) time and O(1) space.
func partitionBySign(nums []int) int {
left, right := 0, len(nums)-1
for left < right {
if nums[right] > 0 {
right--
} else if nums[left] <= 0 {
left++
} else {
nums[left], nums[right] = nums[right], nums[left]
}
}
for left < len(nums) && nums[left] <= 0 {
left++
}
return left
}

// findSmallestPositiveOnly works only on a slice of positive > 0 integers.
// Runs in O(N) since it does two sequential linear scans.
func findSmallestPositiveOnly(nums []int) int {
for i := range nums {
abs := nums[i]
if abs < 0 {
abs = -abs
}
if index := abs - 1; index < len(nums) {
if nums[index] > 0 {
nums[index] = -nums[index]
}
}
}

for i, v := range nums {
if v > 0 {
return i + 1
}
}

return len(nums) + 1
}

// FindSmallestMissingPositive returns the smallest positive number missing.
// Running time is O(N) with O(1) space.
// NOTE: this modifies the input array
func FindSmallestMissingPositive(nums []int) int {
positiveStart := partitionBySign(nums)
return findSmallestPositiveOnly(nums[positiveStart:])
}
35 changes: 35 additions & 0 deletions day4/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package day4

import (
"testing"
)

var testcases = []struct {
input []int
smallestMissingPositive int
}{
{[]int{-10, -20, -40, 1, 2, 3, 4, 5}, 6},
{[]int{3, 4, -1, 1}, 2},
{[]int{1, 2, 0}, 3},
{[]int{1, -1, 2, -2, 0, 100, -100}, 3},
{[]int{-1, -1, -2, -2, 0, -100, -100}, 1},
{[]int{1, 1, 2, 2, 0, 3, 4, 5, 6, 7, 8, 9, 9, 8, -100}, 10},
{[]int{100, 99, 100, -20, -30, -20}, 1},
}

func TestFindSmallestMissingPositive(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
if result := FindSmallestMissingPositive(tc.input); result != tc.smallestMissingPositive {
t.Errorf("Input was %v. I expected %d, but received %d", tc.input, tc.smallestMissingPositive, result)
}
}
}

func BenchmarkFindSmallestMissingPositive(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testcases {
FindSmallestMissingPositive(tc.input)
}
}
}

0 comments on commit 551f318

Please sign in to comment.