Skip to content

Commit

Permalink
Merge b271260 into 2c672e9
Browse files Browse the repository at this point in the history
  • Loading branch information
vaskoz committed Aug 27, 2019
2 parents 2c672e9 + b271260 commit cc4c5da
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 9 deletions.
58 changes: 50 additions & 8 deletions day271/problem.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,60 @@
package day271

import "sort"
import (
"fmt"
"sort"
"strconv"
"strings"
)

// divideBy2 performs the following calculation:
// https://en.wikipedia.org/wiki/Division_by_two#Decimal
// if n is odd, it drops by 1 to the next lower even digit.
func divideBy2(n int) int {
if n&1 == 1 { // odd check without modulo (no division)
n--
}
str := fmt.Sprintf("0%d", n)
var sb strings.Builder
for i := 1; i < len(str); i++ {
d := str[i] - '0'
if (str[i-1]-'0')&1 == 0 { // even
switch d {
case 0, 1:
sb.WriteRune('0')
case 2, 3:
sb.WriteRune('1')
case 4, 5:
sb.WriteRune('2')
case 6, 7:
sb.WriteRune('3')
case 8, 9:
sb.WriteRune('4')
}
} else { // odd
switch d {
case 0, 1:
sb.WriteRune('5')
case 2, 3:
sb.WriteRune('6')
case 4, 5:
sb.WriteRune('7')
case 6, 7:
sb.WriteRune('8')
case 8, 9:
sb.WriteRune('9')
}
}
}
res, _ := strconv.Atoi(sb.String())
return res
}

// BinarySearch is a handwritten binary search.
func BinarySearch(sorted []int, x int) int {
left, right := 0, len(sorted)-1
for left < right {
var mid int
dividend := left + right
divisor := 2
for dividend >= divisor {
dividend -= divisor
mid++
}
mid := divideBy2(left + right)
val := sorted[mid]
switch {
case x == val:
Expand Down
20 changes: 19 additions & 1 deletion day271/problem_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package day271

import "testing"
import (
"math/rand"
"sort"
"testing"
"time"
)

// nolint
var testcases = []struct {
Expand Down Expand Up @@ -45,3 +50,16 @@ func BenchmarkBinarySearchSortPkg(b *testing.B) {
}
}
}

func BenchmarkBinarySearchLargeInput(b *testing.B) {
input := make([]int, 1000000)
rand.Seed(time.Now().UnixNano())
for i := range input {
input[i] = rand.Int()
}
sort.Ints(input)
b.ResetTimer()
for i := 0; i < b.N; i++ {
BinarySearch(input, 1000)
}
}

0 comments on commit cc4c5da

Please sign in to comment.