diff --git a/exercises/practice/pascals-triangle/.meta/example.zig b/exercises/practice/pascals-triangle/.meta/example.zig index 80327467..09772ec1 100644 --- a/exercises/practice/pascals-triangle/.meta/example.zig +++ b/exercises/practice/pascals-triangle/.meta/example.zig @@ -3,13 +3,23 @@ const mem = std.mem; pub fn rows(allocator: mem.Allocator, count: usize) mem.Allocator.Error![][]u128 { var result = try allocator.alloc([]u128, count); - for (0..count) |i| { + var i: usize = 0; + errdefer { + while (i > 0) { + i -= 1; + allocator.free(result[i]); + } + allocator.free(result); + } + + while (i < count) : (i += 1) { result[i] = try allocator.alloc(u128, i + 1); result[i][0] = 1; result[i][i] = 1; - if (i == 0) { + if (i < 2) { continue; } + for (1..i) |j| { result[i][j] = result[i - 1][j - 1] + result[i - 1][j]; } diff --git a/exercises/practice/pascals-triangle/test_pascals_triangle.zig b/exercises/practice/pascals-triangle/test_pascals_triangle.zig index 0ac86b38..56e79bce 100644 --- a/exercises/practice/pascals-triangle/test_pascals_triangle.zig +++ b/exercises/practice/pascals-triangle/test_pascals_triangle.zig @@ -10,11 +10,8 @@ fn free(slices: [][]u128) void { testing.allocator.free(slices); } -test "zero rows" { - const expected = try testing.allocator.alloc([]const u128, 0); - defer testing.allocator.free(expected); - - const actual = try pascals_triangle.rows(testing.allocator, 0); +fn rowsTest(allocator: std.mem.Allocator, count: usize, expected: [][]const u128) anyerror!void { + const actual = try pascals_triangle.rows(allocator, count); defer free(actual); try testing.expectEqual(expected.len, actual.len); @@ -23,107 +20,92 @@ test "zero rows" { } } +test "zero rows" { + const expected: [0][]const u128 = undefined; + try std.testing.checkAllAllocationFailures( + std.testing.allocator, + rowsTest, + .{ 0, &expected }, + ); +} + test "single row" { - var expected = try testing.allocator.alloc([]const u128, 1); + var expected: [1][]const u128 = undefined; expected[0] = &.{1}; - defer testing.allocator.free(expected); - - const actual = try pascals_triangle.rows(testing.allocator, 1); - defer free(actual); - - try testing.expectEqual(expected.len, actual.len); - for (expected, actual) |expected_slice, actual_slice| { - try testing.expectEqualSlices(u128, expected_slice, actual_slice); - } + try std.testing.checkAllAllocationFailures( + std.testing.allocator, + rowsTest, + .{ 1, &expected }, + ); } test "two rows" { - var expected = try testing.allocator.alloc([]const u128, 2); + var expected: [2][]const u128 = undefined; expected[0] = &.{1}; expected[1] = &.{ 1, 1 }; - defer testing.allocator.free(expected); - - const actual = try pascals_triangle.rows(testing.allocator, 2); - defer free(actual); - - try testing.expectEqual(expected.len, actual.len); - for (expected, actual) |expected_slice, actual_slice| { - try testing.expectEqualSlices(u128, expected_slice, actual_slice); - } + try std.testing.checkAllAllocationFailures( + std.testing.allocator, + rowsTest, + .{ 2, &expected }, + ); } test "three rows" { - var expected = try testing.allocator.alloc([]const u128, 3); + var expected: [3][]const u128 = undefined; expected[0] = &.{1}; expected[1] = &.{ 1, 1 }; expected[2] = &.{ 1, 2, 1 }; - defer testing.allocator.free(expected); - - const actual = try pascals_triangle.rows(testing.allocator, 3); - defer free(actual); - - try testing.expectEqual(expected.len, actual.len); - for (expected, actual) |expected_slice, actual_slice| { - try testing.expectEqualSlices(u128, expected_slice, actual_slice); - } + try std.testing.checkAllAllocationFailures( + std.testing.allocator, + rowsTest, + .{ 3, &expected }, + ); } test "four rows" { - var expected = try testing.allocator.alloc([]const u128, 4); + var expected: [4][]const u128 = undefined; expected[0] = &.{1}; expected[1] = &.{ 1, 1 }; expected[2] = &.{ 1, 2, 1 }; expected[3] = &.{ 1, 3, 3, 1 }; - defer testing.allocator.free(expected); - - const actual = try pascals_triangle.rows(testing.allocator, 4); - defer free(actual); - - try testing.expectEqual(expected.len, actual.len); - for (expected, actual) |expected_slice, actual_slice| { - try testing.expectEqualSlices(u128, expected_slice, actual_slice); - } + try std.testing.checkAllAllocationFailures( + std.testing.allocator, + rowsTest, + .{ 4, &expected }, + ); } test "five rows" { - var expected = try testing.allocator.alloc([]const u128, 5); + var expected: [5][]const u128 = undefined; expected[0] = &.{1}; expected[1] = &.{ 1, 1 }; expected[2] = &.{ 1, 2, 1 }; expected[3] = &.{ 1, 3, 3, 1 }; expected[4] = &.{ 1, 4, 6, 4, 1 }; - defer testing.allocator.free(expected); - - const actual = try pascals_triangle.rows(testing.allocator, 5); - defer free(actual); - - try testing.expectEqual(expected.len, actual.len); - for (expected, actual) |expected_slice, actual_slice| { - try testing.expectEqualSlices(u128, expected_slice, actual_slice); - } + try std.testing.checkAllAllocationFailures( + std.testing.allocator, + rowsTest, + .{ 5, &expected }, + ); } test "six rows" { - var expected = try testing.allocator.alloc([]const u128, 6); + var expected: [6][]const u128 = undefined; expected[0] = &.{1}; expected[1] = &.{ 1, 1 }; expected[2] = &.{ 1, 2, 1 }; expected[3] = &.{ 1, 3, 3, 1 }; expected[4] = &.{ 1, 4, 6, 4, 1 }; expected[5] = &.{ 1, 5, 10, 10, 5, 1 }; - defer testing.allocator.free(expected); - - const actual = try pascals_triangle.rows(testing.allocator, 6); - defer free(actual); - - try testing.expectEqual(expected.len, actual.len); - for (expected, actual) |expected_slice, actual_slice| { - try testing.expectEqualSlices(u128, expected_slice, actual_slice); - } + try std.testing.checkAllAllocationFailures( + std.testing.allocator, + rowsTest, + .{ 6, &expected }, + ); } test "ten rows" { - var expected = try testing.allocator.alloc([]const u128, 10); + var expected: [10][]const u128 = undefined; expected[0] = &.{1}; expected[1] = &.{ 1, 1 }; expected[2] = &.{ 1, 2, 1 }; @@ -134,15 +116,11 @@ test "ten rows" { expected[7] = &.{ 1, 7, 21, 35, 35, 21, 7, 1 }; expected[8] = &.{ 1, 8, 28, 56, 70, 56, 28, 8, 1 }; expected[9] = &.{ 1, 9, 36, 84, 126, 126, 84, 36, 9, 1 }; - defer testing.allocator.free(expected); - - const actual = try pascals_triangle.rows(testing.allocator, 10); - defer free(actual); - - try testing.expectEqual(expected.len, actual.len); - for (expected, actual) |expected_slice, actual_slice| { - try testing.expectEqualSlices(u128, expected_slice, actual_slice); - } + try std.testing.checkAllAllocationFailures( + std.testing.allocator, + rowsTest, + .{ 10, &expected }, + ); } test "seventy-five rows" {