Skip to content

Commit

Permalink
Merge pull request #755 from vaskoz/day374
Browse files Browse the repository at this point in the history
Day374
  • Loading branch information
vaskoz committed Nov 29, 2019
2 parents 2fc7372 + d022cc5 commit cab5b52
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)

38 changes: 38 additions & 0 deletions day374/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
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) worst case time thanks to binary search.
func LowestFixedPoint(sorted []int) (int, error) {
if !sort.IntsAreSorted(sorted) {
return 0, errInputNotSorted
}

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

hi = mid
case sorted[mid] < mid:
lo = mid + 1
default:
hi = mid - 1
}
}

return 0, errNoSuchIndex
}
34 changes: 34 additions & 0 deletions day374/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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},
{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 0, nil},
{[]int{-15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, 1, 15}, 15, nil},
}

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 cab5b52

Please sign in to comment.