diff --git a/config.json b/config.json index f4496ff7..3e988261 100644 --- a/config.json +++ b/config.json @@ -228,6 +228,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "slug": "triangle", + "name": "Triangle", + "uuid": "54b9358f-0ce4-46d6-9a61-7eaf0b8d1bdc", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "armstrong-numbers", "name": "Armstrong Numbers", diff --git a/exercises/practice/triangle/.docs/instructions.md b/exercises/practice/triangle/.docs/instructions.md new file mode 100644 index 00000000..ac390087 --- /dev/null +++ b/exercises/practice/triangle/.docs/instructions.md @@ -0,0 +1,29 @@ +# 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 diff --git a/exercises/practice/triangle/.meta/config.json b/exercises/practice/triangle/.meta/config.json new file mode 100644 index 00000000..22258c6e --- /dev/null +++ b/exercises/practice/triangle/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "src/lib.cairo" + ], + "test": [ + "tests/triangle.cairo" + ], + "example": [ + ".meta/example.cairo" + ], + "invalidator": [ + "Scarb.toml" + ] + }, + "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/exercises/practice/triangle/.meta/example.cairo b/exercises/practice/triangle/.meta/example.cairo new file mode 100644 index 00000000..3511abcf --- /dev/null +++ b/exercises/practice/triangle/.meta/example.cairo @@ -0,0 +1,37 @@ +pub fn is_equilateral(sides: [u64; 3]) -> bool { + is_triangle(@sides) && unique_sides(@sides) == 1 +} + +pub fn is_isosceles(sides: [u64; 3]) -> bool { + is_triangle(@sides) && unique_sides(@sides) < 3 +} + +pub fn is_scalene(sides: [u64; 3]) -> bool { + is_triangle(@sides) && unique_sides(@sides) == 3 +} + +fn unique_sides(sides: @[u64; 3]) -> u64 { + let [a, b, c] = sides; + + if a == b && b == c { + 1 + } else if a == b || b == c || a == c { + 2 + } else { + 3 + } +} + +fn is_triangle(sides: @[u64; 3]) -> bool { + let [a, b, c] = sides; + + all_sides_positive(a, b, c) && satisifies_inequality(a, b, c) +} + +fn all_sides_positive(a: @u64, b: @u64, c: @u64) -> bool { + *a > 0 && *b > 0 && *c > 0 +} + +fn satisifies_inequality(a: @u64, b: @u64, c: @u64) -> bool { + *a + *b > *c && *a + *c > *b && *b + *c > *a +} diff --git a/exercises/practice/triangle/.meta/tests.toml b/exercises/practice/triangle/.meta/tests.toml new file mode 100644 index 00000000..2e4a148f --- /dev/null +++ b/exercises/practice/triangle/.meta/tests.toml @@ -0,0 +1,76 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[8b2c43ac-7257-43f9-b552-7631a91988af] +description = "equilateral triangle -> all sides are equal" + +[33eb6f87-0498-4ccf-9573-7f8c3ce92b7b] +description = "equilateral triangle -> any side is unequal" + +[c6585b7d-a8c0-4ad8-8a34-e21d36f7ad87] +description = "equilateral triangle -> no sides are equal" + +[16e8ceb0-eadb-46d1-b892-c50327479251] +description = "equilateral triangle -> all zero sides is not a triangle" + +[3022f537-b8e5-4cc1-8f12-fd775827a00c] +description = "equilateral triangle -> sides may be floats" +include = false + +[cbc612dc-d75a-4c1c-87fc-e2d5edd70b71] +description = "isosceles triangle -> last two sides are equal" + +[e388ce93-f25e-4daf-b977-4b7ede992217] +description = "isosceles triangle -> first two sides are equal" + +[d2080b79-4523-4c3f-9d42-2da6e81ab30f] +description = "isosceles triangle -> first and last sides are equal" + +[8d71e185-2bd7-4841-b7e1-71689a5491d8] +description = "isosceles triangle -> equilateral triangles are also isosceles" + +[840ed5f8-366f-43c5-ac69-8f05e6f10bbb] +description = "isosceles triangle -> no sides are equal" + +[2eba0cfb-6c65-4c40-8146-30b608905eae] +description = "isosceles triangle -> first triangle inequality violation" + +[278469cb-ac6b-41f0-81d4-66d9b828f8ac] +description = "isosceles triangle -> second triangle inequality violation" + +[90efb0c7-72bb-4514-b320-3a3892e278ff] +description = "isosceles triangle -> third triangle inequality violation" + +[adb4ee20-532f-43dc-8d31-e9271b7ef2bc] +description = "isosceles triangle -> sides may be floats" +include = false + +[e8b5f09c-ec2e-47c1-abec-f35095733afb] +description = "scalene triangle -> no sides are equal" + +[2510001f-b44d-4d18-9872-2303e7977dc1] +description = "scalene triangle -> all sides are equal" + +[c6e15a92-90d9-4fb3-90a2-eef64f8d3e1e] +description = "scalene triangle -> first and second sides are equal" + +[3da23a91-a166-419a-9abf-baf4868fd985] +description = "scalene triangle -> first and third sides are equal" + +[b6a75d98-1fef-4c42-8e9a-9db854ba0a4d] +description = "scalene triangle -> second and third sides are equal" + +[70ad5154-0033-48b7-af2c-b8d739cd9fdc] +description = "scalene triangle -> may not violate triangle inequality" + +[26d9d59d-f8f1-40d3-ad58-ae4d54123d7d] +description = "scalene triangle -> sides may be floats" +include = false diff --git a/exercises/practice/triangle/Scarb.toml b/exercises/practice/triangle/Scarb.toml new file mode 100644 index 00000000..6dbf033f --- /dev/null +++ b/exercises/practice/triangle/Scarb.toml @@ -0,0 +1,7 @@ +[package] +name = "triangle" +version = "0.1.0" +edition = "2024_07" + +[dev-dependencies] +cairo_test = "2.7.1" diff --git a/exercises/practice/triangle/src/lib.cairo b/exercises/practice/triangle/src/lib.cairo new file mode 100644 index 00000000..1b31cffe --- /dev/null +++ b/exercises/practice/triangle/src/lib.cairo @@ -0,0 +1,11 @@ +pub fn is_equilateral(sides: [u64; 3]) -> bool { + panic!("implement `is_equilateral`") +} + +pub fn is_isosceles(sides: [u64; 3]) -> bool { + panic!("implement `is_isosceles`") +} + +pub fn is_scalene(sides: [u64; 3]) -> bool { + panic!("implement `is_scalene`") +} diff --git a/exercises/practice/triangle/tests/triangle.cairo b/exercises/practice/triangle/tests/triangle.cairo new file mode 100644 index 00000000..2b8c4f28 --- /dev/null +++ b/exercises/practice/triangle/tests/triangle.cairo @@ -0,0 +1,132 @@ +use triangle::{is_equilateral, is_isosceles, is_scalene}; + +// Equilateral triangles + +#[test] +fn equilateral_all_sides_are_equal() { + let sides: [u64; 3] = [2, 2, 2]; + assert!(is_equilateral(sides)); +} + +#[test] +#[ignore] +fn equilateral_any_side_is_unequal() { + let sides: [u64; 3] = [2, 3, 2]; + assert!(!is_equilateral(sides)); +} + +#[test] +#[ignore] +fn equilateral_no_sides_are_equal() { + let sides: [u64; 3] = [5, 4, 6]; + assert!(!is_equilateral(sides)); +} + +#[test] +#[ignore] +fn equilateral_all_zero_sides_is_not_a_triangle() { + let sides: [u64; 3] = [0, 0, 0]; + assert!(!is_equilateral(sides)); +} + +// Isosceles triangles + +#[test] +#[ignore] +fn isosceles_last_two_sides_are_equal() { + let sides: [u64; 3] = [3, 4, 4]; + assert!(is_isosceles(sides)); +} + +#[test] +#[ignore] +fn isosceles_first_two_sides_are_equal() { + let sides: [u64; 3] = [4, 4, 3]; + assert!(is_isosceles(sides)); +} + +#[test] +#[ignore] +fn isosceles_first_and_last_sides_are_equal() { + let sides: [u64; 3] = [4, 3, 4]; + assert!(is_isosceles(sides)); +} + +#[test] +#[ignore] +fn isosceles_equilateral_triangles_are_also_isosceles() { + let sides: [u64; 3] = [4, 4, 4]; + assert!(is_isosceles(sides)); +} + +#[test] +#[ignore] +fn isosceles_no_sides_are_equal() { + let sides: [u64; 3] = [2, 3, 4]; + assert!(!is_isosceles(sides)); +} + +#[test] +#[ignore] +fn isosceles_first_triangle_inequality_violation() { + let sides: [u64; 3] = [1, 1, 3]; + assert!(!is_isosceles(sides)); +} + +#[test] +#[ignore] +fn isosceles_second_triangle_inequality_violation() { + let sides: [u64; 3] = [1, 3, 1]; + assert!(!is_isosceles(sides)); +} + +#[test] +#[ignore] +fn isosceles_third_triangle_inequality_violation() { + let sides: [u64; 3] = [3, 1, 1]; + assert!(!is_isosceles(sides)); +} + +// Scalene triangles + +#[test] +#[ignore] +fn scalene_no_sides_are_equal() { + let sides: [u64; 3] = [5, 4, 6]; + assert!(is_scalene(sides)); +} + +#[test] +#[ignore] +fn scalene_all_sides_are_equal() { + let sides: [u64; 3] = [4, 4, 4]; + assert!(!is_scalene(sides)); +} + +#[test] +#[ignore] +fn scalene_first_and_second_sides_are_equal() { + let sides: [u64; 3] = [4, 4, 3]; + assert!(!is_scalene(sides)); +} + +#[test] +#[ignore] +fn scalene_first_and_third_sides_are_equal() { + let sides: [u64; 3] = [3, 4, 3]; + assert!(!is_scalene(sides)); +} + +#[test] +#[ignore] +fn scalene_second_and_third_sides_are_equal() { + let sides: [u64; 3] = [4, 3, 3]; + assert!(!is_scalene(sides)); +} + +#[test] +#[ignore] +fn scalene_may_not_violate_triangle_inequality() { + let sides: [u64; 3] = [7, 3, 2]; + assert!(!is_scalene(sides)); +}