Skip to content

Commit

Permalink
exercises(binary-search): return an optional, not an error union (#259)
Browse files Browse the repository at this point in the history
Before this commit, `binary-search` required the user to return an error
when the array of input items:

- was empty
- or did not contain the target

Return an optional instead, like `std.sort.binarySearch` does [1]. Now,
an empty input array is just another case of "value not found".

Also rename `buffer` to `items` for similar consistency with
upstream [1]. Elsewhere we have used the name `buffer` only for a
variable that is mutated by a function.

[1] https://github.com/ziglang/zig/blob/4414f9c46e77/lib/std/sort.zig#L7-L13

Refs: #229
  • Loading branch information
ee7 authored Mar 15, 2023
1 parent fcf24c4 commit a60a991
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 39 deletions.
4 changes: 2 additions & 2 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -384,16 +384,16 @@
"name": "Binary Search",
"practices": [
"control-flow",
"error-sets",
"generics",
"functions",
"optionals",
"type-coercion"
],
"prerequisites": [
"control-flow",
"error-sets",
"generics",
"functions",
"optionals",
"type-coercion"
],
"difficulty": 1
Expand Down
17 changes: 5 additions & 12 deletions exercises/practice/binary-search/.meta/example.zig
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
pub const SearchError = error{
EmptyBuffer,
ValueAbsent,
};

pub fn binarySearch(comptime T: type, target: T, buffer: []const T) SearchError!usize {
if (buffer.len == 0) return SearchError.EmptyBuffer;

pub fn binarySearch(comptime T: type, target: T, items: []const T) ?usize {
var left: usize = 0;
var right = buffer.len;
var right = items.len;

while (left < right) {
const mid = left + (right - left) / 2; // Avoid overflow.
if (buffer[mid] == target) {
if (items[mid] == target) {
return mid;
} else if (buffer[mid] < target) {
} else if (items[mid] < target) {
left = mid + 1;
} else {
right = mid;
}
}
return SearchError.ValueAbsent;
return null;
}
4 changes: 2 additions & 2 deletions exercises/practice/binary-search/binary_search.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Take a look at the tests, you might have to change the function arguments

pub fn binarySearch(target: usize, buffer: []const usize) SearchError!usize {
pub fn binarySearch(target: usize, items: []const usize) ?usize {
_ = target;
_ = buffer;
_ = items;
@compileError("please implement the binarySearch function");
}
45 changes: 22 additions & 23 deletions exercises/practice/binary-search/test_binary_search.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,81 +3,80 @@ const testing = std.testing;

const binary_search = @import("binary_search.zig");
const binarySearch = binary_search.binarySearch;
const SearchError = binary_search.SearchError;

test "finds a value in an array with one element" {
const expected: usize = 0;
const expected: ?usize = 0;
const array = [_]i4{6};
const actual = try binarySearch(i4, 6, &array);
const actual = binarySearch(i4, 6, &array);
try testing.expectEqual(expected, actual);
}

test "finds a value in the middle of an array" {
const expected: usize = 3;
const expected: ?usize = 3;
const array = [_]u4{ 1, 3, 4, 6, 8, 9, 11 };
const actual = try binarySearch(u4, 6, &array);
const actual = binarySearch(u4, 6, &array);
try testing.expectEqual(expected, actual);
}

test "finds a value at the beginning of an array" {
const expected: usize = 0;
const expected: ?usize = 0;
const array = [_]i8{ 1, 3, 4, 6, 8, 9, 11 };
const actual = try binarySearch(i8, 1, &array);
const actual = binarySearch(i8, 1, &array);
try testing.expectEqual(expected, actual);
}

test "finds a value at the end of an array" {
const expected: usize = 6;
const expected: ?usize = 6;
const array = [_]u8{ 1, 3, 4, 6, 8, 9, 11 };
const actual = try binarySearch(u8, 11, &array);
const actual = binarySearch(u8, 11, &array);
try testing.expectEqual(expected, actual);
}

test "finds a value in an array of odd length" {
const expected: usize = 5;
const expected: ?usize = 5;
const array = [_]i16{ 1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634 };
const actual = try binarySearch(i16, 21, &array);
const actual = binarySearch(i16, 21, &array);
try testing.expectEqual(expected, actual);
}

test "finds a value in an array of even length" {
const expected: usize = 5;
const expected: ?usize = 5;
const array = [_]u16{ 1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377 };
const actual = try binarySearch(u16, 21, &array);
const actual = binarySearch(u16, 21, &array);
try testing.expectEqual(expected, actual);
}

test "identifies that a value is not included in the array" {
const expected = SearchError.ValueAbsent;
const expected: ?usize = null;
const array = [_]i32{ 1, 3, 4, 6, 8, 9, 11 };
const actual = binarySearch(i32, 7, &array);
try testing.expectError(expected, actual);
try testing.expectEqual(expected, actual);
}

test "a value smaller than the array's smallest value is not found" {
const expected = SearchError.ValueAbsent;
const expected: ?usize = null;
const array = [_]u32{ 1, 3, 4, 6, 8, 9, 11 };
const actual = binarySearch(u32, 0, &array);
try testing.expectError(expected, actual);
try testing.expectEqual(expected, actual);
}

test "a value larger than the array's largest value is not found" {
const expected = SearchError.ValueAbsent;
const expected: ?usize = null;
const array = [_]i64{ 1, 3, 4, 6, 8, 9, 11 };
const actual = binarySearch(i64, 13, &array);
try testing.expectError(expected, actual);
try testing.expectEqual(expected, actual);
}

test "nothing is found in an empty array" {
const expected = SearchError.EmptyBuffer;
const expected: ?usize = null;
const array = [_]u64{};
const actual = binarySearch(u64, 13, &array);
try testing.expectError(expected, actual);
try testing.expectEqual(expected, actual);
}

test "nothing is found when the left and right bounds cross" {
const expected = SearchError.ValueAbsent;
const expected: ?usize = null;
const array = [_]isize{ 1, 2 };
const actual = binarySearch(isize, 13, &array);
try testing.expectError(expected, actual);
try testing.expectEqual(expected, actual);
}

0 comments on commit a60a991

Please sign in to comment.