Skip to content

Commit

Permalink
exercises(binary-search): example: improve (#254)
Browse files Browse the repository at this point in the history
Changes:

- Make `buffer` no longer an optional. This means we now never return
  `SearchError.NullBuffer`, but there was no test case for that.

- Make the implementation more standard, and avoid overflow when
  calculating `mid`.

I intend to later make this exercise return an optional, not an error
union.

Refs: #229
  • Loading branch information
ee7 authored Mar 15, 2023
1 parent 9fc047a commit 6a2287d
Showing 1 changed file with 13 additions and 22 deletions.
35 changes: 13 additions & 22 deletions exercises/practice/binary-search/.meta/example.zig
Original file line number Diff line number Diff line change
@@ -1,32 +1,23 @@
pub const SearchError = error{
EmptyBuffer,
NullBuffer,
ValueAbsent,
};

pub fn binarySearch(comptime T: type, target: T, buffer: ?[]const T) SearchError!usize {
if (buffer == null) {
return SearchError.NullBuffer;
}
if (buffer.?.len == 0) {
return SearchError.EmptyBuffer;
}
var i: usize = 0;
var j = buffer.?.len - 1;
while (i < j) {
const mid = (i + j) >> 1;
if (buffer.?[mid] < target) {
i = mid + 1;
} else if (buffer.?[mid] > target) {
j = mid - 1;
} else {
pub fn binarySearch(comptime T: type, target: T, buffer: []const T) SearchError!usize {
if (buffer.len == 0) return SearchError.EmptyBuffer;

var left: usize = 0;
var right = buffer.len;

while (left < right) {
const mid = left + (right - left) / 2; // Avoid overflow.
if (buffer[mid] == target) {
return mid;
} else if (buffer[mid] < target) {
left = mid + 1;
} else {
right = mid;
}
}
// Unroll when i == j, otherwise the function logic above might cause
// integer overflow to occur at the edges of usize.
if (buffer.?[i] == target) {
return j;
}
return SearchError.ValueAbsent;
}

0 comments on commit 6a2287d

Please sign in to comment.