Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 248
Good morning! Here's your coding interview problem for today.

This problem was asked by Nvidia.

Find the maximum of two numbers without using any if-else statements, branching, or direct comparisons.

Pull request description:
Day248
Resolves #512.

Patch:
diff --git a/README.md b/README.md
index 660b03a..2a243fd 100644
--- a/README.md
+++ b/README.md
@@ -259,3 +259,4 @@ problems from
 * [Day 245](https://github.com/vaskoz/dailycodingproblem-go/issues/506)
 * [Day 246](https://github.com/vaskoz/dailycodingproblem-go/issues/508)
 * [Day 247](https://github.com/vaskoz/dailycodingproblem-go/issues/510)
+* [Day 248](https://github.com/vaskoz/dailycodingproblem-go/issues/512)
diff --git a/day248/problem.go b/day248/problem.go
new file mode 100644
index 0000000..a7f60d3
--- /dev/null
+++ b/day248/problem.go
@@ -0,0 +1,27 @@
+package day248
+
+// MaxIf is a typical max function using an if branch.
+func MaxIf(a, b int64) int64 {
+	if a > b {
+		return a
+	}
+	return b
+}
+
+// MaxSubtractAndShift finds the max using subtraction
+// and right shifting.
+func MaxSubtractAndShift(a, b int64) int64 {
+	return a - ((a - b) & ((a - b) >> 63))
+}
+
+// MaxXor uses xor and branching to calculate the max.
+// Go requires if branching to convert a bool to an int64.
+// NOTE: No benefit here due to branching if, might as well use MaxIf.
+// Benchmark perf shows actually worse than MaxIf as expected.
+func MaxXor(a, b int64) int64 {
+	bit := int64(0)
+	if a < b {
+		bit = int64(-1)
+	}
+	return a ^ ((a ^ b) & bit)
+}


Test patch:
diff --git a/day248/problem_test.go b/day248/problem_test.go
new file mode 100644
index 0000000..60acc0d
--- /dev/null
+++ b/day248/problem_test.go
@@ -0,0 +1,64 @@
+package day248
+
+import "testing"
+
+// nolint
+var testcases = []struct {
+	a, b, max int64
+}{
+	{10, 20, 20},
+	{20, 1, 20},
+	{30, 2, 30},
+	{1, -2, 1},
+}
+
+func TestMaxIf(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if max := MaxIf(tc.a, tc.b); max != tc.max {
+			t.Errorf("Expected %v, got %v", tc.max, max)
+		}
+	}
+}
+
+func BenchmarkMaxIf(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			MaxIf(tc.a, tc.b)
+		}
+	}
+}
+
+func TestMaxSubtractAndShift(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if max := MaxSubtractAndShift(tc.a, tc.b); max != tc.max {
+			t.Errorf("Expected %v, got %v", tc.max, max)
+		}
+	}
+}
+
+func BenchmarkMaxSubtractAndShift(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			MaxSubtractAndShift(tc.a, tc.b)
+		}
+	}
+}
+
+func TestMaxXor(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if max := MaxXor(tc.a, tc.b); max != tc.max {
+			t.Errorf("Expected %v, got %v", tc.max, max)
+		}
+	}
+}
+
+func BenchmarkMaxXor(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			MaxXor(tc.a, tc.b)
+		}
+	}
+}