1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# Triangle
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. See [Triangle Inequality](https://en.wikipedia.org/wiki/Triangle_inequality).
## Dig Deeper
The case where the sum of the lengths of two sides _equals_ that of the
third is known as a _degenerate_ triangle - it has zero area and looks like
a single line. Feel free to add your own code/tests to check for degenerate triangles.
# Triangle in Rust
- [Result](https://doc.rust-lang.org/std/result/index.html)
Implementation of this can take many forms. Here are some topics that may help you, depending on the approach you take.
- [Enums](https://doc.rust-lang.org/book/2018-edition/ch06-00-enums.html)
- [Traits](https://doc.rust-lang.org/book/2018-edition/ch10-02-traits.html)
- [BTreeSet](https://doc.rust-lang.org/std/collections/btree_set/struct.BTreeSet.html)
Or maybe you will come up with an approach that uses none of those!
## Non-integer lengths
The base exercise tests identification of triangles whose sides are all
integers. However, some triangles cannot be represented by pure integers. A simple example is a right triangle (an isosceles triangle whose equal sides are separated by 90 degrees) whose equal sides both have length of 1. Its hypotenuse is the square root of 2, which is an irrational number: no simple multiplication can represent this number as an integer.
It would be tedious to rewrite the analysis functions to handle both integer and floating-point cases, and particularly tedious to do so for all potential integer and floating point types: given signed and unsigned variants of bitwidths 8, 16, 32, 64, and 128, that would be 10 reimplementations of fundamentally the same code even before considering floats!
There's a better way: [generics](https://doc.rust-lang.org/stable/book/2018-edition/ch10-00-generics.html). By rewriting your Triangle as a `Triangle<T>`, you can write your code once, and hand off the work of generating all those specializations to the compiler. Note that in order to use mathematical operations, you'll need to constrain your generic type to types which support those operations using traits.
There are some bonus tests you can run which test your implementation on floating-point numbers. To enable them, run your tests with the `generic` feature flag, like this:
```bash
cargo test --features generic
```
## Rust Installation
Refer to the [exercism help page][help-page] for Rust installation and learning
resources.
## Writing the Code
Execute the tests with:
```bash
$ cargo test
```
All but the first test have been ignored. After you get the first test to
pass, open the tests source file which is located in the `tests` directory
and remove the `#[ignore]` flag from the next test and get the tests to pass
again. Each separate test is a function with `#[test]` flag above it.
Continue, until you pass every test.
If you wish to run all ignored tests without editing the tests source file, use:
```bash
$ cargo test -- --ignored
```
To run a specific test, for example `some_test`, you can use:
```bash
$ cargo test some_test
```
If the specific test is ignored use:
```bash
$ cargo test some_test -- --ignored
```
To learn more about Rust tests refer to the [online test documentation][rust-tests]
Make sure to read the [Modules][modules] chapter if you
haven't already, it will help you with organizing your files.
## Further improvements
After you have solved the exercise, please consider using the additional utilities, described in the [installation guide](https://exercism.io/tracks/rust/installation), to further refine your final solution.
To format your solution, inside the solution directory use
```bash
cargo fmt
```
To see, if your solution contains some common ineffective use cases, inside the solution directory use
```bash
cargo clippy --all-targets
```
## Submitting the solution
Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer.
## Feedback, Issues, Pull Requests
The [exercism/rust](https://github.com/exercism/rust) repository on GitHub is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help!
If you want to know more about Exercism, take a look at the [contribution guide](https://github.com/exercism/docs/blob/master/contributing-to-language-tracks/README.md).
[help-page]: https://exercism.io/tracks/rust/learning
[modules]: https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html
[cargo]: https://doc.rust-lang.org/book/ch14-00-more-about-cargo.html
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
## Source
The Ruby Koans triangle project, parts 1 & 2 [http://rubykoans.com](http://rubykoans.com)
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|