Skip to content

Commit 049019a

Browse files
Add triangle exercise (#287)
* Add triangle exercise * Apply suggestions from code review Co-authored-by: Bob Hoeppner <[email protected]> --------- Co-authored-by: Bob Hoeppner <[email protected]>
1 parent 1b7dc39 commit 049019a

File tree

9 files changed

+334
-0
lines changed

9 files changed

+334
-0
lines changed

config.json

+16
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,22 @@
12241224
],
12251225
"difficulty": 7
12261226
},
1227+
{
1228+
1229+
"slug": "triangle",
1230+
"name": "Triangle",
1231+
"uuid": "78113af6-b1a4-40ab-86c6-3b26afdec75f",
1232+
"practices": [
1233+
"floating-point-numbers",
1234+
"if-statements"
1235+
],
1236+
"prerequisites": [
1237+
"floating-point-numbers",
1238+
"if-statements",
1239+
"booleans"
1240+
],
1241+
"difficulty": 3
1242+
},
12271243
{
12281244
"slug": "robot-name",
12291245
"name": "Robot Name",

exercises/Exercises.sln

+7
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "DndCharacter", "practice\dn
161161
EndProject
162162
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Poker", "practice\poker\Poker.vbproj", "{F62F286B-2E13-4914-B168-EDB399470B1C}"
163163
EndProject
164+
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Triangle", "practice\triangle\Triangle.vbproj", "{1CE933B5-94BD-48AD-81B9-E352D75020CB}"
165+
EndProject
164166
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "RobotName", "practice\robot-name\RobotName.vbproj", "{B6F54248-A909-42A1-9A75-679160C63B28}"
165167
EndProject
166168
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "TreeBuilding", "practice\tree-building\TreeBuilding.vbproj", "{8CD79257-D9AF-4406-B93D-9C1AF256A6F4}"
@@ -490,6 +492,10 @@ Global
490492
{F62F286B-2E13-4914-B168-EDB399470B1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
491493
{F62F286B-2E13-4914-B168-EDB399470B1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
492494
{F62F286B-2E13-4914-B168-EDB399470B1C}.Release|Any CPU.Build.0 = Release|Any CPU
495+
{1CE933B5-94BD-48AD-81B9-E352D75020CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
496+
{1CE933B5-94BD-48AD-81B9-E352D75020CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
497+
{1CE933B5-94BD-48AD-81B9-E352D75020CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
498+
{1CE933B5-94BD-48AD-81B9-E352D75020CB}.Release|Any CPU.Build.0 = Release|Any CPU
493499
{B6F54248-A909-42A1-9A75-679160C63B28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
494500
{B6F54248-A909-42A1-9A75-679160C63B28}.Debug|Any CPU.Build.0 = Debug|Any CPU
495501
{B6F54248-A909-42A1-9A75-679160C63B28}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -586,6 +592,7 @@ Global
586592
{057DDB74-6435-4B9E-988A-A21895AECE92} = {B161412A-37BB-42B7-9D8F-F4B238E3CFFA}
587593
{1C5BEE1E-B2B8-4D08-BC42-D83121DFFFB9} = {B161412A-37BB-42B7-9D8F-F4B238E3CFFA}
588594
{F62F286B-2E13-4914-B168-EDB399470B1C} = {B161412A-37BB-42B7-9D8F-F4B238E3CFFA}
595+
{1CE933B5-94BD-48AD-81B9-E352D75020CB} = {B161412A-37BB-42B7-9D8F-F4B238E3CFFA}
589596
{B6F54248-A909-42A1-9A75-679160C63B28} = {B161412A-37BB-42B7-9D8F-F4B238E3CFFA}
590597
{8CD79257-D9AF-4406-B93D-9C1AF256A6F4} = {B161412A-37BB-42B7-9D8F-F4B238E3CFFA}
591598
{1F9F3E72-34EE-431B-9955-712E4F8D4220} = {B161412A-37BB-42B7-9D8F-F4B238E3CFFA}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Instructions
2+
3+
Determine if a triangle is equilateral, isosceles, or scalene.
4+
5+
An _equilateral_ triangle has all three sides the same length.
6+
7+
An _isosceles_ triangle has at least two sides the same length.
8+
(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.)
9+
10+
A _scalene_ triangle has all sides of different lengths.
11+
12+
## Note
13+
14+
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.
15+
16+
In equations:
17+
18+
Let `a`, `b`, and `c` be sides of the triangle.
19+
Then all three of the following expressions must be true:
20+
21+
```text
22+
a + b ≥ c
23+
b + c ≥ a
24+
a + c ≥ b
25+
```
26+
27+
See [Triangle Inequality][triangle-inequality]
28+
29+
[triangle-inequality]: https://en.wikipedia.org/wiki/Triangle_inequality
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
Imports System
2+
Imports System.Linq
3+
4+
Public Enum TriangleKind
5+
Equilateral
6+
Isosceles
7+
Scalene
8+
Invalid
9+
End Enum
10+
11+
Module Triangle
12+
Function IsScalene(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As Boolean
13+
Return Kind(side1, side2, side3) = TriangleKind.Scalene
14+
End Function
15+
16+
Function IsIsosceles(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As Boolean
17+
Dim triangle = Kind(side1, side2, side3)
18+
Return triangle = TriangleKind.Isosceles OrElse triangle = TriangleKind.Equilateral
19+
End Function
20+
21+
Function IsEquilateral(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As Boolean
22+
Return Kind(side1, side2, side3) = TriangleKind.Equilateral
23+
End Function
24+
25+
Private Function Kind(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As TriangleKind
26+
If AllSidesAreZero(side1, side2, side3) OrElse HasImpossibleSides(side1, side2, side3) OrElse ViolatesTriangleInequality(side1, side2, side3) Then
27+
Return TriangleKind.Invalid
28+
End If
29+
30+
Dim uniqueSides As Integer = GetUniqueSides(side1, side2, side3)
31+
If uniqueSides = 1 Then Return TriangleKind.Equilateral
32+
If uniqueSides = 2 Then Return TriangleKind.Isosceles
33+
Return TriangleKind.Scalene
34+
End Function
35+
36+
Private Function AllSidesAreZero(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As Boolean
37+
Return side1 = 0 AndAlso side2 = 0 AndAlso side3 = 0
38+
End Function
39+
40+
Private Function HasImpossibleSides(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As Boolean
41+
Return side1 < 0 OrElse side2 < 0 OrElse side3 < 0
42+
End Function
43+
44+
Private Function ViolatesTriangleInequality(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As Boolean
45+
Return side1 + side2 <= side3 OrElse side1 + side3 <= side2 OrElse side2 + side3 <= side1
46+
End Function
47+
48+
Private Function GetUniqueSides(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As Integer
49+
Dim sides As Double() = {side1, side2, side3}
50+
Return sides.Distinct().Count()
51+
End Function
52+
End Module
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"authors": [
3+
"ErikSchierboom",
4+
"bobahop"
5+
],
6+
"files": {
7+
"solution": [
8+
"Triangle.vb"
9+
],
10+
"test": [
11+
"TriangleTests.vb"
12+
],
13+
"example": [
14+
".meta/Example.vb"
15+
]
16+
},
17+
"blurb": "Determine if a triangle is equilateral, isosceles, or scalene.",
18+
"source": "The Ruby Koans triangle project, parts 1 & 2",
19+
"source_url": "https://web.archive.org/web/20220831105330/http://rubykoans.com"
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[8b2c43ac-7257-43f9-b552-7631a91988af]
13+
description = "equilateral triangle -> all sides are equal"
14+
15+
[33eb6f87-0498-4ccf-9573-7f8c3ce92b7b]
16+
description = "equilateral triangle -> any side is unequal"
17+
18+
[c6585b7d-a8c0-4ad8-8a34-e21d36f7ad87]
19+
description = "equilateral triangle -> no sides are equal"
20+
21+
[16e8ceb0-eadb-46d1-b892-c50327479251]
22+
description = "equilateral triangle -> all zero sides is not a triangle"
23+
24+
[3022f537-b8e5-4cc1-8f12-fd775827a00c]
25+
description = "equilateral triangle -> sides may be floats"
26+
27+
[cbc612dc-d75a-4c1c-87fc-e2d5edd70b71]
28+
description = "isosceles triangle -> last two sides are equal"
29+
30+
[e388ce93-f25e-4daf-b977-4b7ede992217]
31+
description = "isosceles triangle -> first two sides are equal"
32+
33+
[d2080b79-4523-4c3f-9d42-2da6e81ab30f]
34+
description = "isosceles triangle -> first and last sides are equal"
35+
36+
[8d71e185-2bd7-4841-b7e1-71689a5491d8]
37+
description = "isosceles triangle -> equilateral triangles are also isosceles"
38+
39+
[840ed5f8-366f-43c5-ac69-8f05e6f10bbb]
40+
description = "isosceles triangle -> no sides are equal"
41+
42+
[2eba0cfb-6c65-4c40-8146-30b608905eae]
43+
description = "isosceles triangle -> first triangle inequality violation"
44+
45+
[278469cb-ac6b-41f0-81d4-66d9b828f8ac]
46+
description = "isosceles triangle -> second triangle inequality violation"
47+
48+
[90efb0c7-72bb-4514-b320-3a3892e278ff]
49+
description = "isosceles triangle -> third triangle inequality violation"
50+
51+
[adb4ee20-532f-43dc-8d31-e9271b7ef2bc]
52+
description = "isosceles triangle -> sides may be floats"
53+
54+
[e8b5f09c-ec2e-47c1-abec-f35095733afb]
55+
description = "scalene triangle -> no sides are equal"
56+
57+
[2510001f-b44d-4d18-9872-2303e7977dc1]
58+
description = "scalene triangle -> all sides are equal"
59+
60+
[c6e15a92-90d9-4fb3-90a2-eef64f8d3e1e]
61+
description = "scalene triangle -> first and second sides are equal"
62+
63+
[3da23a91-a166-419a-9abf-baf4868fd985]
64+
description = "scalene triangle -> first and third sides are equal"
65+
66+
[b6a75d98-1fef-4c42-8e9a-9db854ba0a4d]
67+
description = "scalene triangle -> second and third sides are equal"
68+
69+
[70ad5154-0033-48b7-af2c-b8d739cd9fdc]
70+
description = "scalene triangle -> may not violate triangle inequality"
71+
72+
[26d9d59d-f8f1-40d3-ad58-ae4d54123d7d]
73+
description = "scalene triangle -> sides may be floats"
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Imports System
2+
3+
Public Module Triangle
4+
Public Function IsScalene(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As Boolean
5+
Throw New NotImplementedException("You need to implement this function.")
6+
End Function
7+
8+
Public Function IsIsosceles(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As Boolean
9+
Throw New NotImplementedException("You need to implement this function.")
10+
End Function
11+
12+
Public Function IsEquilateral(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double) As Boolean
13+
Throw New NotImplementedException("You need to implement this function.")
14+
End Function
15+
End Module
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net7.0</TargetFramework>
4+
</PropertyGroup>
5+
6+
<ItemGroup>
7+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
8+
<PackageReference Include="xunit" Version="2.4.2" />
9+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
10+
<PrivateAssets>all</PrivateAssets>
11+
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
12+
</PackageReference>
13+
</ItemGroup>
14+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
Imports Xunit
2+
3+
Public Class TriangleTests
4+
<Fact>
5+
Public Sub Equilateral_triangle_all_sides_are_equal()
6+
Assert.True(IsEquilateral(2, 2, 2))
7+
End Sub
8+
9+
<Fact(Skip:="Remove this Skip property to run this test")>
10+
Public Sub Equilateral_triangle_any_side_is_unequal()
11+
Assert.False(IsEquilateral(2, 3, 2))
12+
End Sub
13+
14+
<Fact(Skip:="Remove this Skip property to run this test")>
15+
Public Sub Equilateral_triangle_no_sides_are_equal()
16+
Assert.False(IsEquilateral(5, 4, 6))
17+
End Sub
18+
19+
<Fact(Skip:="Remove this Skip property to run this test")>
20+
Public Sub Equilateral_triangle_all_zero_sides_is_not_a_triangle()
21+
Assert.False(IsEquilateral(0, 0, 0))
22+
End Sub
23+
24+
<Fact(Skip:="Remove this Skip property to run this test")>
25+
Public Sub Equilateral_triangle_sides_may_be_floats()
26+
Assert.True(IsEquilateral(0.5, 0.5, 0.5))
27+
End Sub
28+
29+
<Fact(Skip:="Remove this Skip property to run this test")>
30+
Public Sub Isosceles_triangle_last_two_sides_are_equal()
31+
Assert.True(IsIsosceles(3, 4, 4))
32+
End Sub
33+
34+
<Fact(Skip:="Remove this Skip property to run this test")>
35+
Public Sub Isosceles_triangle_first_two_sides_are_equal()
36+
Assert.True(IsIsosceles(4, 4, 3))
37+
End Sub
38+
39+
<Fact(Skip:="Remove this Skip property to run this test")>
40+
Public Sub Isosceles_triangle_first_and_last_sides_are_equal()
41+
Assert.True(IsIsosceles(4, 3, 4))
42+
End Sub
43+
44+
<Fact(Skip:="Remove this Skip property to run this test")>
45+
Public Sub Isosceles_triangle_equilateral_triangles_are_also_isosceles()
46+
Assert.True(IsIsosceles(4, 4, 4))
47+
End Sub
48+
49+
<Fact(Skip:="Remove this Skip property to run this test")>
50+
Public Sub Isosceles_triangle_no_sides_are_equal()
51+
Assert.False(IsIsosceles(2, 3, 4))
52+
End Sub
53+
54+
<Fact(Skip:="Remove this Skip property to run this test")>
55+
Public Sub Isosceles_triangle_first_triangle_inequality_violation()
56+
Assert.False(IsIsosceles(1, 1, 3))
57+
End Sub
58+
59+
<Fact(Skip:="Remove this Skip property to run this test")>
60+
Public Sub Isosceles_triangle_second_triangle_inequality_violation()
61+
Assert.False(IsIsosceles(1, 3, 1))
62+
End Sub
63+
64+
<Fact(Skip:="Remove this Skip property to run this test")>
65+
Public Sub Isosceles_triangle_third_triangle_inequality_violation()
66+
Assert.False(IsIsosceles(3, 1, 1))
67+
End Sub
68+
69+
<Fact(Skip:="Remove this Skip property to run this test")>
70+
Public Sub Isosceles_triangle_sides_may_be_floats()
71+
Assert.True(IsIsosceles(0.5, 0.4, 0.5))
72+
End Sub
73+
74+
<Fact(Skip:="Remove this Skip property to run this test")>
75+
Public Sub Scalene_triangle_no_sides_are_equal()
76+
Assert.True(IsScalene(5, 4, 6))
77+
End Sub
78+
79+
<Fact(Skip:="Remove this Skip property to run this test")>
80+
Public Sub Scalene_triangle_all_sides_are_equal()
81+
Assert.False(IsScalene(4, 4, 4))
82+
End Sub
83+
84+
<Fact(Skip:="Remove this Skip property to run this test")>
85+
Public Sub Scalene_triangle_first_and_second_sides_are_equal()
86+
Assert.False(IsScalene(4, 4, 3))
87+
End Sub
88+
89+
<Fact(Skip:="Remove this Skip property to run this test")>
90+
Public Sub Scalene_triangle_first_and_third_sides_are_equal()
91+
Assert.False(IsScalene(3, 4, 3))
92+
End Sub
93+
94+
<Fact(Skip:="Remove this Skip property to run this test")>
95+
Public Sub Scalene_triangle_second_and_third_sides_are_equal()
96+
Assert.False(IsScalene(4, 3, 3))
97+
End Sub
98+
99+
<Fact(Skip:="Remove this Skip property to run this test")>
100+
Public Sub Scalene_triangle_may_not_violate_triangle_inequality()
101+
Assert.False(IsScalene(7, 3, 2))
102+
End Sub
103+
104+
<Fact(Skip:="Remove this Skip property to run this test")>
105+
Public Sub Scalene_triangle_sides_may_be_floats()
106+
Assert.True(IsScalene(0.5, 0.4, 0.6))
107+
End Sub
108+
End Class

0 commit comments

Comments
 (0)