Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 317
Good morning! Here's your coding interview problem for today.

This problem was asked by Yahoo.

Write a function that returns the bitwise **_AND_** of all integers between `M` and `N`, inclusive.

Pull request description:
Day317
Resolves #645.

Patch:
diff --git a/README.md b/README.md
index 0b12102..939059e 100644
--- a/README.md
+++ b/README.md
@@ -322,3 +322,4 @@ problems from
 * [Day 312](https://github.com/vaskoz/dailycodingproblem-go/issues/637)
 * [Day 314](https://github.com/vaskoz/dailycodingproblem-go/issues/640)
 * [Day 315](https://github.com/vaskoz/dailycodingproblem-go/issues/642)
+* [Day 317](https://github.com/vaskoz/dailycodingproblem-go/issues/645)
diff --git a/day317/problem.go b/day317/problem.go
new file mode 100644
index 0000000..2f18885
--- /dev/null
+++ b/day317/problem.go
@@ -0,0 +1,38 @@
+package day317
+
+import (
+	"math/bits"
+)
+
+// BitwiseAndInclusiveRange returns the AND of all the numbers
+// between m and n inclusive.
+// This runs by performing O(abs(N-M)) AND operations.
+// This is a brute force solution.
+func BitwiseAndInclusiveRange(m, n uint64) uint64 {
+	if m > n {
+		m, n = n, m
+	}
+	for i := m + 1; m != 0 && i <= n; i++ {
+		m &= i
+	}
+	return m
+}
+
+// BitwiseAndInclusiveRangeFaster returns the AND of all the numbers
+// between m and n inclusive.
+// This is a smarter bit manipulation version.
+func BitwiseAndInclusiveRangeFaster(m, n uint64) uint64 {
+	var result uint64
+	for {
+		mMsb := bits.Len64(m)
+		nMsb := bits.Len64(n)
+		if mMsb != nMsb || mMsb == 0 {
+			break
+		}
+		val := uint64(1 << (uint(mMsb) - 1))
+		result += val
+		m -= val
+		n -= val
+	}
+	return result
+}


Test patch:
diff --git a/day317/problem_test.go b/day317/problem_test.go
new file mode 100644
index 0000000..5f695de
--- /dev/null
+++ b/day317/problem_test.go
@@ -0,0 +1,49 @@
+package day317
+
+import "testing"
+
+// nolint
+var testcases = []struct {
+	m, n, expected uint64
+}{
+	{1, 10, 0},
+	{12, 15, 12},
+	{10, 1, 0},
+	{15, 12, 12},
+	{19, 17, 16},
+	{20, 10, 0},
+}
+
+func TestBitwiseAndInclusiveRange(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if result := BitwiseAndInclusiveRange(tc.m, tc.n); result != tc.expected {
+			t.Errorf("Expected %v, got %v", tc.expected, result)
+		}
+	}
+}
+
+func BenchmarkBitwiseAndInclusiveRange(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			BitwiseAndInclusiveRange(tc.m, tc.n)
+		}
+	}
+}
+
+func TestBitwiseAndInclusiveRangeFaster(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if result := BitwiseAndInclusiveRangeFaster(tc.m, tc.n); result != tc.expected {
+			t.Errorf("Expected %v, got %v", tc.expected, result)
+		}
+	}
+}
+
+func BenchmarkBitwiseAndInclusiveRangeFaster(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			BitwiseAndInclusiveRangeFaster(tc.m, tc.n)
+		}
+	}
+}