Skip to content

Commit

Permalink
Merge 3340768 into 2fc7372
Browse files Browse the repository at this point in the history
  • Loading branch information
vaskoz committed Nov 28, 2019
2 parents 2fc7372 + 3340768 commit acc6a9e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,4 +369,5 @@ problems from
* [Day 371](https://github.com/vaskoz/dailycodingproblem-go/issues/750)
* [Day 372](https://github.com/vaskoz/dailycodingproblem-go/issues/748)
* [Day 373](https://github.com/vaskoz/dailycodingproblem-go/issues/752)
* [Day 374](https://github.com/vaskoz/dailycodingproblem-go/issues/754)

40 changes: 40 additions & 0 deletions day374/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package day374

import (
"errors"
"sort"
)

var (
errNoSuchIndex = errors.New("no index is a fixed point")
errInputNotSorted = errors.New("input is not sorted and must be")
)

// LowestFixedPoint returns the lowest fixed point index.
// If no such index exists, it returns an error.
// Also returns an error if input is not sorted.
// Runs in O(log N) time thanks to binary search.
// Worse case is O(N/2) because I iterate down from a match
// to find the lowest fixed point.
func LowestFixedPoint(sorted []int) (int, error) {
if !sort.IntsAreSorted(sorted) {
return 0, errInputNotSorted
}

for lo, hi := 0, len(sorted)-1; lo < hi; {
switch mid := (lo + hi) / 2; {
case sorted[mid] == mid:
for sorted[mid] == mid {
mid--
}

return mid + 1, nil
case sorted[mid] > mid:
hi = mid - 1
default:
lo = mid + 1
}
}

return 0, errNoSuchIndex
}
32 changes: 32 additions & 0 deletions day374/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package day374

import "testing"

// nolint
var testcases = []struct {
input []int
expected int
expectedErr error
}{
{[]int{-5, -3, 2, 3}, 2, nil},
{[]int{2, 3, -3}, 0, errInputNotSorted},
{[]int{-5, -3, 5, 13}, 0, errNoSuchIndex},
}

func TestLowestFixedPoint(t *testing.T) {
t.Parallel()

for _, tc := range testcases {
if res, err := LowestFixedPoint(tc.input); res != tc.expected || err != tc.expectedErr {
t.Errorf("Expected (%v,%v), got (%v,%v)", tc.expected, tc.expectedErr, res, err)
}
}
}

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

0 comments on commit acc6a9e

Please sign in to comment.