diff --git a/zig/triangle/.exercism/config.json b/zig/triangle/.exercism/config.json new file mode 100644 index 0000000..765cd20 --- /dev/null +++ b/zig/triangle/.exercism/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "massivelivefun" + ], + "files": { + "solution": [ + "triangle.zig" + ], + "test": [ + "test_triangle.zig" + ], + "example": [ + ".meta/example.zig" + ] + }, + "blurb": "Determine if a triangle is equilateral, isosceles, or scalene.", + "source": "The Ruby Koans triangle project, parts 1 & 2", + "source_url": "https://web.archive.org/web/20220831105330/http://rubykoans.com" +} diff --git a/zig/triangle/.exercism/metadata.json b/zig/triangle/.exercism/metadata.json new file mode 100644 index 0000000..5382418 --- /dev/null +++ b/zig/triangle/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"zig","exercise":"triangle","id":"60a9b567b2b646e7a31fc3b2ac5ee623","url":"https://exercism.org/tracks/zig/exercises/triangle","handle":"Chomp1295","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/zig/triangle/HELP.md b/zig/triangle/HELP.md new file mode 100644 index 0000000..de13b1d --- /dev/null +++ b/zig/triangle/HELP.md @@ -0,0 +1,53 @@ +# Help + +## Running the tests + +Write your code in `.zig`. + +To run the tests for an exercise, run: + +```bash +zig test test_exercise_name.zig +``` + +in the exercise's root directory (replacing `exercise_name` with the name of the exercise). + +## Submitting your solution + +You can submit your solution using the `exercism submit triangle.zig` command. +This command will upload your solution to the Exercism website and print the solution page's URL. + +It's possible to submit an incomplete solution which allows you to: + +- See how others have completed the exercise +- Request help from a mentor + +## Need to get help? + +If you'd like help solving the exercise, check the following pages: + +- The [Zig track's documentation](https://exercism.org/docs/tracks/zig) +- The [Zig track's programming category on the forum](https://forum.exercism.org/c/programming/zig) +- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +- [The Zig Programming Language Documentation][documentation] is a great overview of all of the language features that Zig provides to those who use it. +- [Zig Guide][zig-guide] is an excellent primer that explains the language features that Zig has to offer. +- [Ziglings][ziglings] is highly recommended. + Learn Zig by fixing tiny broken programs. +- [The Zig Programming Language Discord][discord-zig] is the main [Discord][discord]. + It provides a great way to get in touch with the Zig community at large, and get some quick, direct help for any Zig related problem. +- [#zig][irc] on irc.freenode.net is the main Zig IRC channel. +- [/r/Zig][reddit] is the main Zig subreddit. +- [Stack Overflow][stack-overflow] can be used to discover code snippets and solutions to problems that may have already asked and maybe solved by others. + +[discord]: https://discordapp.com +[discord-zig]: https://discord.com/invite/gxsFFjE +[documentation]: https://ziglang.org/documentation/master +[irc]: https://webchat.freenode.net/?channels=%23zig +[reddit]: https://www.reddit.com/r/Zig +[stack-overflow]: https://stackoverflow.com/questions/tagged/zig +[zig-guide]: https://zig.guide/ +[ziglings]: https://codeberg.org/ziglings/exercises \ No newline at end of file diff --git a/zig/triangle/README.md b/zig/triangle/README.md new file mode 100644 index 0000000..7ecb561 --- /dev/null +++ b/zig/triangle/README.md @@ -0,0 +1,44 @@ +# Triangle + +Welcome to Triangle on Exercism's Zig Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Determine if a triangle is equilateral, isosceles, or scalene. + +An _equilateral_ triangle has all three sides the same length. + +An _isosceles_ triangle has at least two sides the same length. +(It is sometimes specified as having exactly two sides the same length, but for the purposes of this exercise we'll say at least two.) + +A _scalene_ triangle has all sides of different lengths. + +## Note + +For a shape to be a triangle at all, all sides have to be of length > 0, and the sum of the lengths of any two sides must be greater than or equal to the length of the third side. + +In equations: + +Let `a`, `b`, and `c` be sides of the triangle. +Then all three of the following expressions must be true: + +```text +a + b ≥ c +b + c ≥ a +a + c ≥ b +``` + +See [Triangle Inequality][triangle-inequality] + +[triangle-inequality]: https://en.wikipedia.org/wiki/Triangle_inequality + +## Source + +### Created by + +- @massivelivefun + +### Based on + +The Ruby Koans triangle project, parts 1 & 2 - https://web.archive.org/web/20220831105330/http://rubykoans.com \ No newline at end of file diff --git a/zig/triangle/test_triangle.zig b/zig/triangle/test_triangle.zig new file mode 100644 index 0000000..9f6a1a0 --- /dev/null +++ b/zig/triangle/test_triangle.zig @@ -0,0 +1,109 @@ +const std = @import("std"); +const testing = std.testing; + +const triangle = @import("triangle.zig"); + +test "equilateral all sides are equal" { + const actual = try triangle.Triangle.init(2, 2, 2); + try testing.expect(actual.isEquilateral()); +} + +test "equilateral any side is unequal" { + const actual = try triangle.Triangle.init(2, 3, 2); + try testing.expect(!actual.isEquilateral()); +} + +test "equilateral no sides are equal" { + const actual = try triangle.Triangle.init(5, 4, 6); + try testing.expect(!actual.isEquilateral()); +} + +test "equilateral all zero sides is not a triangle" { + const actual = triangle.Triangle.init(0, 0, 0); + try testing.expectError(triangle.TriangleError.Invalid, actual); +} + +test "equilateral sides may be floats" { + const actual = try triangle.Triangle.init(0.5, 0.5, 0.5); + try testing.expect(actual.isEquilateral()); +} + +test "isosceles last two sides are equal" { + const actual = try triangle.Triangle.init(3, 4, 4); + try testing.expect(actual.isIsosceles()); +} + +test "isosceles first two sides are equal" { + const actual = try triangle.Triangle.init(4, 4, 3); + try testing.expect(actual.isIsosceles()); +} + +test "isosceles first and last sides are equal" { + const actual = try triangle.Triangle.init(4, 3, 4); + try testing.expect(actual.isIsosceles()); +} + +test "equilateral triangles are also isosceles" { + const actual = try triangle.Triangle.init(4, 3, 4); + try testing.expect(actual.isIsosceles()); +} + +test "isosceles no sides are equal" { + const actual = try triangle.Triangle.init(2, 3, 4); + try testing.expect(!actual.isIsosceles()); +} + +test "isosceles first triangle inequality violation" { + const actual = triangle.Triangle.init(1, 1, 3); + try testing.expectError(triangle.TriangleError.Invalid, actual); +} + +test "isosceles second triangle inequality violation" { + const actual = triangle.Triangle.init(1, 3, 1); + try testing.expectError(triangle.TriangleError.Invalid, actual); +} + +test "isosceles third triangle inequality violation" { + const actual = triangle.Triangle.init(3, 1, 1); + try testing.expectError(triangle.TriangleError.Invalid, actual); +} + +test "isosceles sides may be floats" { + const actual = try triangle.Triangle.init(0.5, 0.4, 0.5); + try testing.expect(actual.isIsosceles()); +} + +test "scalene no sides are equal" { + const actual = try triangle.Triangle.init(5, 4, 6); + try testing.expect(actual.isScalene()); +} + +test "scalene all sides are equal" { + const actual = try triangle.Triangle.init(4, 4, 4); + try testing.expect(!actual.isScalene()); +} + +test "scalene first and second sides are equal" { + const actual = try triangle.Triangle.init(4, 4, 3); + try testing.expect(!actual.isScalene()); +} + +test "scalene first and third sides are equal" { + const actual = try triangle.Triangle.init(3, 4, 3); + try testing.expect(!actual.isScalene()); +} + +test "scalene second and third sides are equal" { + const actual = try triangle.Triangle.init(4, 3, 3); + try testing.expect(!actual.isScalene()); +} + +test "scalene may not violate triangle inequality" { + const actual = triangle.Triangle.init(7, 3, 2); + try testing.expectError(triangle.TriangleError.Invalid, actual); +} + +test "scalene sides may be floats" { + const actual = try triangle.Triangle.init(0.5, 0.4, 0.6); + try testing.expect(actual.isScalene()); +} diff --git a/zig/triangle/triangle.zig b/zig/triangle/triangle.zig new file mode 100644 index 0000000..b7b6e19 --- /dev/null +++ b/zig/triangle/triangle.zig @@ -0,0 +1,31 @@ +pub const TriangleError = error{Invalid}; + +pub const Triangle = struct { + a: f64, + b: f64, + c: f64, + + fn isValid(a: f64, b: f64, c: f64) bool { + return (a > 0 and b > 0 and c > 0) and (a + b >= c and b + c >= a and a + c >= b); + } + + pub fn init(a: f64, b: f64, c: f64) TriangleError!Triangle { + if (!isValid(a, b, c)) { + return error.Invalid; + } + + return Triangle{ .a = a, .b = b, .c = c }; + } + + pub fn isEquilateral(self: Triangle) bool { + return self.a == self.b and self.b == self.c; + } + + pub fn isIsosceles(self: Triangle) bool { + return self.a == self.b or self.a == self.c or self.b == self.c; + } + + pub fn isScalene(self: Triangle) bool { + return self.a != self.b and self.a != self.c and self.b != self.c; + } +};