Initial commit

This commit is contained in:
2022-08-04 23:58:25 +02:00
commit ff1c36fc24
447 changed files with 9869 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
# Project exclude paths
/low-power-embedded-game/target/
/magazine-cutout/target/

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/rust.iml" filepath="$PROJECT_DIR$/.idea/rust.iml" />
</modules>
</component>
</project>

85
.idea/rust.iml generated Normal file
View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="CPP_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/clock/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/clock/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/low-power-embedded-game/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/low-power-embedded-game/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/poker/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/poker/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/resistor-color/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resistor-color/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/short-fibonacci/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/short-fibonacci/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/sublist/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/sublist/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/anagram/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/anagram/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/gigasecond/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/gigasecond/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/reverse-string/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/reverse-string/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/space-age/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/space-age/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/armstrong-numbers/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/armstrong-numbers/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/magazine-cutout/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/magazine-cutout/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/minesweeper/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/minesweeper/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/beer-song/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/beer-song/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/high-scores/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/high-scores/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/all-your-base/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/all-your-base/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/bob/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/bob/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/grade-school/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/grade-school/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/leap/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/leap/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/paasio/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/paasio/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/parallel-letter-frequency/benches" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/parallel-letter-frequency/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/parallel-letter-frequency/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/proverb/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/proverb/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/robot-simulator/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/robot-simulator/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/scrabble-score/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/scrabble-score/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tournament/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tournament/tests" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/sublist/target" />
<excludeFolder url="file://$MODULE_DIR$/poker/target" />
<excludeFolder url="file://$MODULE_DIR$/clock/target" />
<excludeFolder url="file://$MODULE_DIR$/resistor-color/target" />
<excludeFolder url="file://$MODULE_DIR$/short-fibonacci/target" />
<excludeFolder url="file://$MODULE_DIR$/low-power-embedded-game/target" />
<excludeFolder url="file://$MODULE_DIR$/reverse-string/target" />
<excludeFolder url="file://$MODULE_DIR$/gigasecond/target" />
<excludeFolder url="file://$MODULE_DIR$/anagram/target" />
<excludeFolder url="file://$MODULE_DIR$/space-age/target" />
<excludeFolder url="file://$MODULE_DIR$/minesweeper/target" />
<excludeFolder url="file://$MODULE_DIR$/magazine-cutout/target" />
<excludeFolder url="file://$MODULE_DIR$/armstrong-numbers/target" />
<excludeFolder url="file://$MODULE_DIR$/beer-song/target" />
<excludeFolder url="file://$MODULE_DIR$/high-scores/target" />
<excludeFolder url="file://$MODULE_DIR$/paasio/target" />
<excludeFolder url="file://$MODULE_DIR$/proverb/target" />
<excludeFolder url="file://$MODULE_DIR$/robot-simulator/target" />
<excludeFolder url="file://$MODULE_DIR$/bob/target" />
<excludeFolder url="file://$MODULE_DIR$/leap/target" />
<excludeFolder url="file://$MODULE_DIR$/grade-school/target" />
<excludeFolder url="file://$MODULE_DIR$/tournament/target" />
<excludeFolder url="file://$MODULE_DIR$/scrabble-score/target" />
<excludeFolder url="file://$MODULE_DIR$/all-your-base/target" />
<excludeFolder url="file://$MODULE_DIR$/parallel-letter-frequency/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,36 @@
{
"blurb": "Convert a number, represented as a sequence of digits in one base, to any other base.",
"authors": [
"jonasbb"
],
"contributors": [
"CGMossa",
"coriolinus",
"cwhakes",
"efx",
"ErikSchierboom",
"IanWhitney",
"lutostag",
"mkantor",
"navossoc",
"nfiles",
"pedantic79",
"petertseng",
"rofrol",
"stringparser",
"xakon",
"ZapAnton"
],
"files": {
"solution": [
"src/lib.rs",
"Cargo.toml"
],
"test": [
"tests/all-your-base.rs"
],
"example": [
".meta/example.rs"
]
}
}

View File

@@ -0,0 +1 @@
{"track":"rust","exercise":"all-your-base","id":"22568dbd27034998a766c1e5833e585d","url":"https://exercism.org/tracks/rust/exercises/all-your-base","handle":"ArthurDanjou","is_requester":true,"auto_approve":false}

8
all-your-base/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
# Generated by Cargo
# will have compiled files and executables
/target/
**/*.rs.bk
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock

4
all-your-base/Cargo.toml Normal file
View File

@@ -0,0 +1,4 @@
[package]
edition = "2021"
name = "allyourbase"
version = "1.0.0"

85
all-your-base/HELP.md Normal file
View File

@@ -0,0 +1,85 @@
# Help
## Running the tests
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 _only ignored_ tests without editing the tests source file, use:
```bash
$ cargo test -- --ignored
```
If you are using Rust 1.51 or later, you can run _all_ tests with
```bash
$ cargo test -- --include-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].
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
## Submitting your solution
You can submit your solution using the `exercism submit src/lib.rs Cargo.toml` 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 [Rust track's documentation](https://exercism.org/docs/tracks/rust)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
## Rust Installation
Refer to the [exercism help page][help-page] for Rust installation and learning
resources.
## 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 GitHub [track repository][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].
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
[help-page]: https://exercism.org/tracks/rust/learning
[github]: https://github.com/exercism/rust
[contribution guide]: https://exercism.org/docs/community/contributors

62
all-your-base/README.md Normal file
View File

@@ -0,0 +1,62 @@
# All Your Base
Welcome to All Your Base on Exercism's Rust Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Convert a number, represented as a sequence of digits in one base, to any other base.
Implement general base conversion. Given a number in base **a**,
represented as a sequence of digits, convert it to base **b**.
## Note
- Try to implement the conversion yourself.
Do not use something else to perform the conversion for you.
## About [Positional Notation](https://en.wikipedia.org/wiki/Positional_notation)
In positional notation, a number in base **b** can be understood as a linear
combination of powers of **b**.
The number 42, *in base 10*, means:
(4 * 10^1) + (2 * 10^0)
The number 101010, *in base 2*, means:
(1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (0 * 2^0)
The number 1120, *in base 3*, means:
(1 * 3^3) + (1 * 3^2) + (2 * 3^1) + (0 * 3^0)
I think you got the idea!
*Yes. Those three numbers above are exactly the same. Congratulations!*
## Source
### Created by
- @jonasbb
### Contributed to by
- @CGMossa
- @coriolinus
- @cwhakes
- @efx
- @ErikSchierboom
- @IanWhitney
- @lutostag
- @mkantor
- @navossoc
- @nfiles
- @pedantic79
- @petertseng
- @rofrol
- @stringparser
- @xakon
- @ZapAnton

68
all-your-base/src/lib.rs Normal file
View File

@@ -0,0 +1,68 @@
#[derive(Debug, PartialEq, Eq)]
pub enum Error {
InvalidInputBase,
InvalidOutputBase,
InvalidDigit(u32),
}
///
/// Convert a number between two bases.
///
/// A number is any slice of digits.
/// A digit is any unsigned integer (e.g. u8, u16, u32, u64, or usize).
/// Bases are specified as unsigned integers.
///
/// Return an `Err(.)` if the conversion is impossible.
/// The tests do not test for specific values inside the `Err(.)`.
///
///
/// You are allowed to change the function signature as long as all test still pass.
///
///
/// Example:
/// Input
/// number: &[4, 2]
/// from_base: 10
/// to_base: 2
/// Result
/// Ok(vec![1, 0, 1, 0, 1, 0])
///
/// The example corresponds to converting the number 42 from decimal
/// which is equivalent to 101010 in binary.
///
///
/// Notes:
/// * The empty slice ( "[]" ) is equal to the number 0.
/// * Never output leading 0 digits, unless the input number is 0, in which the output must be `[0]`.
/// However, your function must be able to process input with leading 0 digits.
///
pub fn convert(number: &[u32], from_base: u32, to_base: u32) -> Result<Vec<u32>, Error> {
if from_base < 2 {
return Err(Error::InvalidInputBase);
}
if to_base < 2 {
return Err(Error::InvalidOutputBase);
}
let mut value: u32 = 0;
for &n in number.iter() {
if n >= from_base {
return Err(Error::InvalidDigit(n))
} else {
value = value * from_base + n;
}
}
let mut result = Vec::new();
while value != 0 {
result.push(value % to_base);
value /= to_base;
}
if result.is_empty() {
result.push(0);
}
result.reverse();
Ok(result)
}

View File

@@ -0,0 +1,216 @@
use allyourbase as ayb;
#[test]
fn single_bit_one_to_decimal() {
let input_base = 2;
let input_digits = &[1];
let output_base = 10;
let output_digits = vec![1];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn binary_to_single_decimal() {
let input_base = 2;
let input_digits = &[1, 0, 1];
let output_base = 10;
let output_digits = vec![5];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn single_decimal_to_binary() {
let input_base = 10;
let input_digits = &[5];
let output_base = 2;
let output_digits = vec![1, 0, 1];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn binary_to_multiple_decimal() {
let input_base = 2;
let input_digits = &[1, 0, 1, 0, 1, 0];
let output_base = 10;
let output_digits = vec![4, 2];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn decimal_to_binary() {
let input_base = 10;
let input_digits = &[4, 2];
let output_base = 2;
let output_digits = vec![1, 0, 1, 0, 1, 0];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn trinary_to_hexadecimal() {
let input_base = 3;
let input_digits = &[1, 1, 2, 0];
let output_base = 16;
let output_digits = vec![2, 10];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn hexadecimal_to_trinary() {
let input_base = 16;
let input_digits = &[2, 10];
let output_base = 3;
let output_digits = vec![1, 1, 2, 0];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn fifteen_bit_integer() {
let input_base = 97;
let input_digits = &[3, 46, 60];
let output_base = 73;
let output_digits = vec![6, 10, 45];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn empty_list() {
let input_base = 2;
let input_digits = &[];
let output_base = 10;
let output_digits = vec![0];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn single_zero() {
let input_base = 10;
let input_digits = &[0];
let output_base = 2;
let output_digits = vec![0];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn multiple_zeros() {
let input_base = 10;
let input_digits = &[0, 0, 0];
let output_base = 2;
let output_digits = vec![0];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn leading_zeros() {
let input_base = 7;
let input_digits = &[0, 6, 0];
let output_base = 10;
let output_digits = vec![4, 2];
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Ok(output_digits)
);
}
#[test]
#[ignore]
fn invalid_positive_digit() {
let input_base = 2;
let input_digits = &[1, 2, 1, 0, 1, 0];
let output_base = 10;
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Err(ayb::Error::InvalidDigit(2))
);
}
#[test]
#[ignore]
fn input_base_is_one() {
let input_base = 1;
let input_digits = &[];
let output_base = 10;
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Err(ayb::Error::InvalidInputBase)
);
}
#[test]
#[ignore]
fn output_base_is_one() {
let input_base = 2;
let input_digits = &[1, 0, 1, 0, 1, 0];
let output_base = 1;
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Err(ayb::Error::InvalidOutputBase)
);
}
#[test]
#[ignore]
fn input_base_is_zero() {
let input_base = 0;
let input_digits = &[];
let output_base = 10;
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Err(ayb::Error::InvalidInputBase)
);
}
#[test]
#[ignore]
fn output_base_is_zero() {
let input_base = 10;
let input_digits = &[7];
let output_base = 0;
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Err(ayb::Error::InvalidOutputBase)
);
}

View File

@@ -0,0 +1,47 @@
{
"blurb": "Given a word and a list of possible anagrams, select the correct sublist.",
"authors": [
"EduardoBautista"
],
"contributors": [
"andrewclarkson",
"ashleygwilliams",
"bobahop",
"chancancode",
"ClashTheBunny",
"coriolinus",
"cwhakes",
"Dimkar3000",
"EduardoBautista",
"efx",
"ErikSchierboom",
"gris",
"IanWhitney",
"kytrinyx",
"lutostag",
"mkantor",
"nfiles",
"petertseng",
"pminten",
"quartsize",
"rofrol",
"stevejb71",
"stringparser",
"xakon",
"ZapAnton"
],
"files": {
"solution": [
"src/lib.rs",
"Cargo.toml"
],
"test": [
"tests/anagram.rs"
],
"example": [
".meta/example.rs"
]
},
"source": "Inspired by the Extreme Startup game",
"source_url": "https://github.com/rchatley/extreme_startup"
}

View File

@@ -0,0 +1 @@
{"track":"rust","exercise":"anagram","id":"5abb5b06fa2749eb88cee51e987ac255","url":"https://exercism.org/tracks/rust/exercises/anagram","handle":"ArthurDanjou","is_requester":true,"auto_approve":false}

8
anagram/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
# Generated by Cargo
# will have compiled files and executables
/target/
**/*.rs.bk
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock

4
anagram/Cargo.toml Normal file
View File

@@ -0,0 +1,4 @@
[package]
edition = "2021"
name = "anagram"
version = "0.0.0"

85
anagram/HELP.md Normal file
View File

@@ -0,0 +1,85 @@
# Help
## Running the tests
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 _only ignored_ tests without editing the tests source file, use:
```bash
$ cargo test -- --ignored
```
If you are using Rust 1.51 or later, you can run _all_ tests with
```bash
$ cargo test -- --include-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].
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
## Submitting your solution
You can submit your solution using the `exercism submit src/lib.rs Cargo.toml` 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 [Rust track's documentation](https://exercism.org/docs/tracks/rust)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
## Rust Installation
Refer to the [exercism help page][help-page] for Rust installation and learning
resources.
## 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 GitHub [track repository][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].
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
[help-page]: https://exercism.org/tracks/rust/learning
[github]: https://github.com/exercism/rust
[contribution guide]: https://exercism.org/docs/community/contributors

61
anagram/README.md Normal file
View File

@@ -0,0 +1,61 @@
# Anagram
Welcome to Anagram on Exercism's Rust Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
An anagram is a rearrangement of letters to form a new word.
Given a word and a list of candidates, select the sublist of anagrams of the given word.
Given `"listen"` and a list of candidates like `"enlists" "google"
"inlets" "banana"` the program should return a list containing
`"inlets"`.
The solution is case insensitive, which means `"WOrd"` is the same as `"word"` or `"woRd"`. It may help to take a peek at the [std library](https://doc.rust-lang.org/std/primitive.char.html) for functions that can convert between them.
The solution cannot contain the input word. A word is always an anagram of itself, which means it is not an interesting result. Given `"hello"` and the list `["hello", "olleh"]` the answer is `["olleh"]`.
You are going to have to adjust the function signature provided in the stub in order for the lifetimes to work out properly. This is intentional: what's there demonstrates the basics of lifetime syntax, and what's missing teaches how to interpret lifetime-related compiler errors.
Try to limit case changes. Case changes are expensive in terms of time, so it's faster to minimize them.
If sorting, consider [sort_unstable](https://doc.rust-lang.org/std/primitive.slice.html#method.sort_unstable) which is typically faster than stable sorting. When applicable, unstable sorting is preferred because it is generally faster than stable sorting and it doesn't allocate auxiliary memory.
## Source
### Created by
- @EduardoBautista
### Contributed to by
- @andrewclarkson
- @ashleygwilliams
- @bobahop
- @chancancode
- @ClashTheBunny
- @coriolinus
- @cwhakes
- @Dimkar3000
- @EduardoBautista
- @efx
- @ErikSchierboom
- @gris
- @IanWhitney
- @kytrinyx
- @lutostag
- @mkantor
- @nfiles
- @petertseng
- @pminten
- @quartsize
- @rofrol
- @stevejb71
- @stringparser
- @xakon
- @ZapAnton
### Based on
Inspired by the Extreme Startup game - https://github.com/rchatley/extreme_startup

25
anagram/src/lib.rs Normal file
View File

@@ -0,0 +1,25 @@
use std::collections::HashSet;
pub fn anagrams_for<'a>(word: &str, possible_anagrams: &[&'a str]) -> HashSet<&'a str> {
let to_lowercase_s = |c: char| {
if !c.is_lowercase() {
c.to_lowercase().to_string()
} else {
c.to_string()
}
};
let lw: Vec<_> = word.chars().map(to_lowercase_s).collect();
let mut sc: Vec<_> = word.chars().map(to_lowercase_s).collect();
sc.sort_unstable();
let result = possible_anagrams.iter()
.filter(|w| {
let mut sci: Vec<_> = w.chars().map(to_lowercase_s).collect();
let same_word = lw == sci;
sci.sort_unstable();
sci == sc && !same_word
}).map(|&w| w);
HashSet::from_iter(result)
}

186
anagram/tests/anagram.rs Normal file
View File

@@ -0,0 +1,186 @@
use std::collections::HashSet;
fn process_anagram_case(word: &str, inputs: &[&str], expected: &[&str]) {
let result = anagram::anagrams_for(word, inputs);
let expected: HashSet<&str> = expected.iter().cloned().collect();
assert_eq!(result, expected);
}
#[test]
fn test_no_matches() {
let word = "diaper";
let inputs = ["hello", "world", "zombies", "pants"];
let outputs = vec![];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_detect_simple_anagram() {
let word = "ant";
let inputs = ["tan", "stand", "at"];
let outputs = vec!["tan"];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_does_not_confuse_different_duplicates() {
let word = "galea";
let inputs = ["eagle"];
let outputs = vec![];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_eliminate_anagram_subsets() {
let word = "good";
let inputs = ["dog", "goody"];
let outputs = vec![];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_detect_anagram() {
let word = "listen";
let inputs = ["enlists", "google", "inlets", "banana"];
let outputs = vec!["inlets"];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_multiple_anagrams() {
let word = "allergy";
let inputs = [
"gallery",
"ballerina",
"regally",
"clergy",
"largely",
"leading",
];
let outputs = vec!["gallery", "regally", "largely"];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_case_insensitive_anagrams() {
let word = "Orchestra";
let inputs = ["cashregister", "Carthorse", "radishes"];
let outputs = vec!["Carthorse"];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_unicode_anagrams() {
let word = "ΑΒΓ";
// These words don't make sense, they're just greek letters cobbled together.
let inputs = ["ΒΓΑ", "ΒΓΔ", "γβα"];
let outputs = vec!["ΒΓΑ", "γβα"];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_misleading_unicode_anagrams() {
// Despite what a human might think these words contain different letters, the input uses Greek
// A and B while the list of potential anagrams uses Latin A and B.
let word = "ΑΒΓ";
let inputs = ["ABΓ"];
let outputs = vec![];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_does_not_detect_a_word_as_its_own_anagram() {
let word = "banana";
let inputs = ["banana"];
let outputs = vec![];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_does_not_detect_a_differently_cased_word_as_its_own_anagram() {
let word = "banana";
let inputs = ["bAnana"];
let outputs = vec![];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_does_not_detect_a_differently_cased_unicode_word_as_its_own_anagram() {
let word = "ΑΒΓ";
let inputs = ["ΑΒγ"];
let outputs = vec![];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_same_bytes_different_chars() {
let word = "a⬂"; // 61 E2 AC 82
let inputs = ["€a"]; // E2 82 AC 61
let outputs = vec![];
process_anagram_case(word, &inputs, &outputs);
}
#[test]
#[ignore]
fn test_different_words_but_same_ascii_sum() {
let word = "bc";
let inputs = ["ad"];
let outputs = vec![];
process_anagram_case(word, &inputs, &outputs);
}

View File

@@ -0,0 +1,36 @@
{
"blurb": "Determine if a number is an Armstrong number",
"authors": [
"shingtaklam1324"
],
"contributors": [
"AndrewKvalheim",
"coriolinus",
"cwhakes",
"eddyp",
"efx",
"ErikSchierboom",
"lutostag",
"ocstl",
"petertseng",
"rofrol",
"sputnick1124",
"stringparser",
"xakon",
"ZapAnton"
],
"files": {
"solution": [
"src/lib.rs",
"Cargo.toml"
],
"test": [
"tests/armstrong-numbers.rs"
],
"example": [
".meta/example.rs"
]
},
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Narcissistic_number"
}

View File

@@ -0,0 +1 @@
{"track":"rust","exercise":"armstrong-numbers","id":"a40568d0bf3448af81f78f78a233cb45","url":"https://exercism.org/tracks/rust/exercises/armstrong-numbers","handle":"ArthurDanjou","is_requester":true,"auto_approve":false}

8
armstrong-numbers/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
# Generated by Cargo
# will have compiled files and executables
/target/
**/*.rs.bk
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock

View File

@@ -0,0 +1,4 @@
[package]
edition = "2021"
name = "armstrong_numbers"
version = "1.1.0"

85
armstrong-numbers/HELP.md Normal file
View File

@@ -0,0 +1,85 @@
# Help
## Running the tests
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 _only ignored_ tests without editing the tests source file, use:
```bash
$ cargo test -- --ignored
```
If you are using Rust 1.51 or later, you can run _all_ tests with
```bash
$ cargo test -- --include-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].
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
## Submitting your solution
You can submit your solution using the `exercism submit src/lib.rs Cargo.toml` 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 [Rust track's documentation](https://exercism.org/docs/tracks/rust)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
## Rust Installation
Refer to the [exercism help page][help-page] for Rust installation and learning
resources.
## 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 GitHub [track repository][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].
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
[help-page]: https://exercism.org/tracks/rust/learning
[github]: https://github.com/exercism/rust
[contribution guide]: https://exercism.org/docs/community/contributors

View File

@@ -0,0 +1,44 @@
# Armstrong Numbers
Welcome to Armstrong Numbers on Exercism's Rust Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
An [Armstrong number](https://en.wikipedia.org/wiki/Narcissistic_number) is a number that is the sum of its own digits each raised to the power of the number of digits.
For example:
- 9 is an Armstrong number, because `9 = 9^1 = 9`
- 10 is *not* an Armstrong number, because `10 != 1^2 + 0^2 = 1`
- 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153`
- 154 is *not* an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190`
Write some code to determine whether a number is an Armstrong number.
## Source
### Created by
- @shingtaklam1324
### Contributed to by
- @AndrewKvalheim
- @coriolinus
- @cwhakes
- @eddyp
- @efx
- @ErikSchierboom
- @lutostag
- @ocstl
- @petertseng
- @rofrol
- @sputnick1124
- @stringparser
- @xakon
- @ZapAnton
### Based on
Wikipedia - https://en.wikipedia.org/wiki/Narcissistic_number

View File

@@ -0,0 +1,8 @@
pub fn is_armstrong_number(num: u32) -> bool {
num == num
.to_string()
.chars()
.map(|c| c.to_digit(10).unwrap())
.map(|d| d.pow(num.to_string().len() as u32))
.sum()
}

View File

@@ -0,0 +1,54 @@
use armstrong_numbers::*;
#[test]
fn test_zero_is_an_armstrong_number() {
assert!(is_armstrong_number(0))
}
#[test]
#[ignore]
fn test_single_digit_numbers_are_armstrong_numbers() {
assert!(is_armstrong_number(5))
}
#[test]
#[ignore]
fn test_there_are_no_2_digit_armstrong_numbers() {
assert!(!is_armstrong_number(10))
}
#[test]
#[ignore]
fn test_three_digit_armstrong_number() {
assert!(is_armstrong_number(153))
}
#[test]
#[ignore]
fn test_three_digit_non_armstrong_number() {
assert!(!is_armstrong_number(100))
}
#[test]
#[ignore]
fn test_four_digit_armstrong_number() {
assert!(is_armstrong_number(9474))
}
#[test]
#[ignore]
fn test_four_digit_non_armstrong_number() {
assert!(!is_armstrong_number(9475))
}
#[test]
#[ignore]
fn test_seven_digit_armstrong_number() {
assert!(is_armstrong_number(9_926_315))
}
#[test]
#[ignore]
fn test_seven_digit_non_armstrong_number() {
assert!(!is_armstrong_number(9_926_316))
}

View File

@@ -0,0 +1,44 @@
{
"blurb": "Produce the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.",
"authors": [
"EduardoBautista"
],
"contributors": [
"andrewclarkson",
"ashleygwilliams",
"coriolinus",
"cwhakes",
"EduardoBautista",
"efx",
"ErikSchierboom",
"IanWhitney",
"kytrinyx",
"leoyvens",
"lutostag",
"mkantor",
"murlakatamenka",
"navossoc",
"nfiles",
"petertseng",
"pminten",
"razielgn",
"rofrol",
"stringparser",
"xakon",
"ZapAnton"
],
"files": {
"solution": [
"src/lib.rs",
"Cargo.toml"
],
"test": [
"tests/beer-song.rs"
],
"example": [
".meta/example.rs"
]
},
"source": "Learn to Program by Chris Pine",
"source_url": "http://pine.fm/LearnToProgram/?Chapter=06"
}

View File

@@ -0,0 +1 @@
{"track":"rust","exercise":"beer-song","id":"73cb4eea0081401d9672503aa42beb65","url":"https://exercism.org/tracks/rust/exercises/beer-song","handle":"ArthurDanjou","is_requester":true,"auto_approve":false}

8
beer-song/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
# Generated by Cargo
# will have compiled files and executables
/target/
**/*.rs.bk
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock

4
beer-song/Cargo.toml Normal file
View File

@@ -0,0 +1,4 @@
[package]
edition = "2021"
name = "beer-song"
version = "0.0.0"

85
beer-song/HELP.md Normal file
View File

@@ -0,0 +1,85 @@
# Help
## Running the tests
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 _only ignored_ tests without editing the tests source file, use:
```bash
$ cargo test -- --ignored
```
If you are using Rust 1.51 or later, you can run _all_ tests with
```bash
$ cargo test -- --include-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].
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
## Submitting your solution
You can submit your solution using the `exercism submit src/lib.rs Cargo.toml` 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 [Rust track's documentation](https://exercism.org/docs/tracks/rust)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
## Rust Installation
Refer to the [exercism help page][help-page] for Rust installation and learning
resources.
## 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 GitHub [track repository][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].
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
[help-page]: https://exercism.org/tracks/rust/learning
[github]: https://github.com/exercism/rust
[contribution guide]: https://exercism.org/docs/community/contributors

361
beer-song/README.md Normal file
View File

@@ -0,0 +1,361 @@
# Beer Song
Welcome to Beer Song on Exercism's Rust Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Recite the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.
Note that not all verses are identical.
```text
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.
98 bottles of beer on the wall, 98 bottles of beer.
Take one down and pass it around, 97 bottles of beer on the wall.
97 bottles of beer on the wall, 97 bottles of beer.
Take one down and pass it around, 96 bottles of beer on the wall.
96 bottles of beer on the wall, 96 bottles of beer.
Take one down and pass it around, 95 bottles of beer on the wall.
95 bottles of beer on the wall, 95 bottles of beer.
Take one down and pass it around, 94 bottles of beer on the wall.
94 bottles of beer on the wall, 94 bottles of beer.
Take one down and pass it around, 93 bottles of beer on the wall.
93 bottles of beer on the wall, 93 bottles of beer.
Take one down and pass it around, 92 bottles of beer on the wall.
92 bottles of beer on the wall, 92 bottles of beer.
Take one down and pass it around, 91 bottles of beer on the wall.
91 bottles of beer on the wall, 91 bottles of beer.
Take one down and pass it around, 90 bottles of beer on the wall.
90 bottles of beer on the wall, 90 bottles of beer.
Take one down and pass it around, 89 bottles of beer on the wall.
89 bottles of beer on the wall, 89 bottles of beer.
Take one down and pass it around, 88 bottles of beer on the wall.
88 bottles of beer on the wall, 88 bottles of beer.
Take one down and pass it around, 87 bottles of beer on the wall.
87 bottles of beer on the wall, 87 bottles of beer.
Take one down and pass it around, 86 bottles of beer on the wall.
86 bottles of beer on the wall, 86 bottles of beer.
Take one down and pass it around, 85 bottles of beer on the wall.
85 bottles of beer on the wall, 85 bottles of beer.
Take one down and pass it around, 84 bottles of beer on the wall.
84 bottles of beer on the wall, 84 bottles of beer.
Take one down and pass it around, 83 bottles of beer on the wall.
83 bottles of beer on the wall, 83 bottles of beer.
Take one down and pass it around, 82 bottles of beer on the wall.
82 bottles of beer on the wall, 82 bottles of beer.
Take one down and pass it around, 81 bottles of beer on the wall.
81 bottles of beer on the wall, 81 bottles of beer.
Take one down and pass it around, 80 bottles of beer on the wall.
80 bottles of beer on the wall, 80 bottles of beer.
Take one down and pass it around, 79 bottles of beer on the wall.
79 bottles of beer on the wall, 79 bottles of beer.
Take one down and pass it around, 78 bottles of beer on the wall.
78 bottles of beer on the wall, 78 bottles of beer.
Take one down and pass it around, 77 bottles of beer on the wall.
77 bottles of beer on the wall, 77 bottles of beer.
Take one down and pass it around, 76 bottles of beer on the wall.
76 bottles of beer on the wall, 76 bottles of beer.
Take one down and pass it around, 75 bottles of beer on the wall.
75 bottles of beer on the wall, 75 bottles of beer.
Take one down and pass it around, 74 bottles of beer on the wall.
74 bottles of beer on the wall, 74 bottles of beer.
Take one down and pass it around, 73 bottles of beer on the wall.
73 bottles of beer on the wall, 73 bottles of beer.
Take one down and pass it around, 72 bottles of beer on the wall.
72 bottles of beer on the wall, 72 bottles of beer.
Take one down and pass it around, 71 bottles of beer on the wall.
71 bottles of beer on the wall, 71 bottles of beer.
Take one down and pass it around, 70 bottles of beer on the wall.
70 bottles of beer on the wall, 70 bottles of beer.
Take one down and pass it around, 69 bottles of beer on the wall.
69 bottles of beer on the wall, 69 bottles of beer.
Take one down and pass it around, 68 bottles of beer on the wall.
68 bottles of beer on the wall, 68 bottles of beer.
Take one down and pass it around, 67 bottles of beer on the wall.
67 bottles of beer on the wall, 67 bottles of beer.
Take one down and pass it around, 66 bottles of beer on the wall.
66 bottles of beer on the wall, 66 bottles of beer.
Take one down and pass it around, 65 bottles of beer on the wall.
65 bottles of beer on the wall, 65 bottles of beer.
Take one down and pass it around, 64 bottles of beer on the wall.
64 bottles of beer on the wall, 64 bottles of beer.
Take one down and pass it around, 63 bottles of beer on the wall.
63 bottles of beer on the wall, 63 bottles of beer.
Take one down and pass it around, 62 bottles of beer on the wall.
62 bottles of beer on the wall, 62 bottles of beer.
Take one down and pass it around, 61 bottles of beer on the wall.
61 bottles of beer on the wall, 61 bottles of beer.
Take one down and pass it around, 60 bottles of beer on the wall.
60 bottles of beer on the wall, 60 bottles of beer.
Take one down and pass it around, 59 bottles of beer on the wall.
59 bottles of beer on the wall, 59 bottles of beer.
Take one down and pass it around, 58 bottles of beer on the wall.
58 bottles of beer on the wall, 58 bottles of beer.
Take one down and pass it around, 57 bottles of beer on the wall.
57 bottles of beer on the wall, 57 bottles of beer.
Take one down and pass it around, 56 bottles of beer on the wall.
56 bottles of beer on the wall, 56 bottles of beer.
Take one down and pass it around, 55 bottles of beer on the wall.
55 bottles of beer on the wall, 55 bottles of beer.
Take one down and pass it around, 54 bottles of beer on the wall.
54 bottles of beer on the wall, 54 bottles of beer.
Take one down and pass it around, 53 bottles of beer on the wall.
53 bottles of beer on the wall, 53 bottles of beer.
Take one down and pass it around, 52 bottles of beer on the wall.
52 bottles of beer on the wall, 52 bottles of beer.
Take one down and pass it around, 51 bottles of beer on the wall.
51 bottles of beer on the wall, 51 bottles of beer.
Take one down and pass it around, 50 bottles of beer on the wall.
50 bottles of beer on the wall, 50 bottles of beer.
Take one down and pass it around, 49 bottles of beer on the wall.
49 bottles of beer on the wall, 49 bottles of beer.
Take one down and pass it around, 48 bottles of beer on the wall.
48 bottles of beer on the wall, 48 bottles of beer.
Take one down and pass it around, 47 bottles of beer on the wall.
47 bottles of beer on the wall, 47 bottles of beer.
Take one down and pass it around, 46 bottles of beer on the wall.
46 bottles of beer on the wall, 46 bottles of beer.
Take one down and pass it around, 45 bottles of beer on the wall.
45 bottles of beer on the wall, 45 bottles of beer.
Take one down and pass it around, 44 bottles of beer on the wall.
44 bottles of beer on the wall, 44 bottles of beer.
Take one down and pass it around, 43 bottles of beer on the wall.
43 bottles of beer on the wall, 43 bottles of beer.
Take one down and pass it around, 42 bottles of beer on the wall.
42 bottles of beer on the wall, 42 bottles of beer.
Take one down and pass it around, 41 bottles of beer on the wall.
41 bottles of beer on the wall, 41 bottles of beer.
Take one down and pass it around, 40 bottles of beer on the wall.
40 bottles of beer on the wall, 40 bottles of beer.
Take one down and pass it around, 39 bottles of beer on the wall.
39 bottles of beer on the wall, 39 bottles of beer.
Take one down and pass it around, 38 bottles of beer on the wall.
38 bottles of beer on the wall, 38 bottles of beer.
Take one down and pass it around, 37 bottles of beer on the wall.
37 bottles of beer on the wall, 37 bottles of beer.
Take one down and pass it around, 36 bottles of beer on the wall.
36 bottles of beer on the wall, 36 bottles of beer.
Take one down and pass it around, 35 bottles of beer on the wall.
35 bottles of beer on the wall, 35 bottles of beer.
Take one down and pass it around, 34 bottles of beer on the wall.
34 bottles of beer on the wall, 34 bottles of beer.
Take one down and pass it around, 33 bottles of beer on the wall.
33 bottles of beer on the wall, 33 bottles of beer.
Take one down and pass it around, 32 bottles of beer on the wall.
32 bottles of beer on the wall, 32 bottles of beer.
Take one down and pass it around, 31 bottles of beer on the wall.
31 bottles of beer on the wall, 31 bottles of beer.
Take one down and pass it around, 30 bottles of beer on the wall.
30 bottles of beer on the wall, 30 bottles of beer.
Take one down and pass it around, 29 bottles of beer on the wall.
29 bottles of beer on the wall, 29 bottles of beer.
Take one down and pass it around, 28 bottles of beer on the wall.
28 bottles of beer on the wall, 28 bottles of beer.
Take one down and pass it around, 27 bottles of beer on the wall.
27 bottles of beer on the wall, 27 bottles of beer.
Take one down and pass it around, 26 bottles of beer on the wall.
26 bottles of beer on the wall, 26 bottles of beer.
Take one down and pass it around, 25 bottles of beer on the wall.
25 bottles of beer on the wall, 25 bottles of beer.
Take one down and pass it around, 24 bottles of beer on the wall.
24 bottles of beer on the wall, 24 bottles of beer.
Take one down and pass it around, 23 bottles of beer on the wall.
23 bottles of beer on the wall, 23 bottles of beer.
Take one down and pass it around, 22 bottles of beer on the wall.
22 bottles of beer on the wall, 22 bottles of beer.
Take one down and pass it around, 21 bottles of beer on the wall.
21 bottles of beer on the wall, 21 bottles of beer.
Take one down and pass it around, 20 bottles of beer on the wall.
20 bottles of beer on the wall, 20 bottles of beer.
Take one down and pass it around, 19 bottles of beer on the wall.
19 bottles of beer on the wall, 19 bottles of beer.
Take one down and pass it around, 18 bottles of beer on the wall.
18 bottles of beer on the wall, 18 bottles of beer.
Take one down and pass it around, 17 bottles of beer on the wall.
17 bottles of beer on the wall, 17 bottles of beer.
Take one down and pass it around, 16 bottles of beer on the wall.
16 bottles of beer on the wall, 16 bottles of beer.
Take one down and pass it around, 15 bottles of beer on the wall.
15 bottles of beer on the wall, 15 bottles of beer.
Take one down and pass it around, 14 bottles of beer on the wall.
14 bottles of beer on the wall, 14 bottles of beer.
Take one down and pass it around, 13 bottles of beer on the wall.
13 bottles of beer on the wall, 13 bottles of beer.
Take one down and pass it around, 12 bottles of beer on the wall.
12 bottles of beer on the wall, 12 bottles of beer.
Take one down and pass it around, 11 bottles of beer on the wall.
11 bottles of beer on the wall, 11 bottles of beer.
Take one down and pass it around, 10 bottles of beer on the wall.
10 bottles of beer on the wall, 10 bottles of beer.
Take one down and pass it around, 9 bottles of beer on the wall.
9 bottles of beer on the wall, 9 bottles of beer.
Take one down and pass it around, 8 bottles of beer on the wall.
8 bottles of beer on the wall, 8 bottles of beer.
Take one down and pass it around, 7 bottles of beer on the wall.
7 bottles of beer on the wall, 7 bottles of beer.
Take one down and pass it around, 6 bottles of beer on the wall.
6 bottles of beer on the wall, 6 bottles of beer.
Take one down and pass it around, 5 bottles of beer on the wall.
5 bottles of beer on the wall, 5 bottles of beer.
Take one down and pass it around, 4 bottles of beer on the wall.
4 bottles of beer on the wall, 4 bottles of beer.
Take one down and pass it around, 3 bottles of beer on the wall.
3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.
1 bottle of beer on the wall, 1 bottle of beer.
Take it down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
```
## For bonus points
Did you get the tests passing and the code clean? If you want to, these
are some additional things you could try:
* Remove as much duplication as you possibly can.
* Optimize for readability, even if it means introducing duplication.
* If you've removed all the duplication, do you have a lot of
conditionals? Try replacing the conditionals with polymorphism, if it
applies in this language. How readable is it?
Then please share your thoughts in a comment on the submission. Did this
experiment make the code better? Worse? Did you learn anything from it?
## Source
### Created by
- @EduardoBautista
### Contributed to by
- @andrewclarkson
- @ashleygwilliams
- @coriolinus
- @cwhakes
- @EduardoBautista
- @efx
- @ErikSchierboom
- @IanWhitney
- @kytrinyx
- @leoyvens
- @lutostag
- @mkantor
- @murlakatamenka
- @navossoc
- @nfiles
- @petertseng
- @pminten
- @razielgn
- @rofrol
- @stringparser
- @xakon
- @ZapAnton
### Based on
Learn to Program by Chris Pine - http://pine.fm/LearnToProgram/?Chapter=06

23
beer-song/src/lib.rs Normal file
View File

@@ -0,0 +1,23 @@
const VERSES: [&str; 3] = [
"No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n",
"1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n",
"2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n"
];
pub fn verse(n: u32) -> String {
match n {
0 => VERSES[0].to_string(),
1 => VERSES[1].to_string(),
2 => VERSES[2].to_string(),
_ => format!("{0} bottles of beer on the wall, {0} bottles of beer.\n\
Take one down and pass it around, {1} bottles of beer on the wall.\n", n, n-1)
}
}
pub fn sing(start: u32, end: u32) -> String {
(end .. start + 1)
.rev()
.map(|n| verse(n))
.collect::<Vec<_>>()
.join("\n")
}

View File

@@ -0,0 +1,36 @@
use beer_song as beer;
#[test]
fn test_verse_0() {
assert_eq!(beer::verse(0), "No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n");
}
#[test]
#[ignore]
fn test_verse_1() {
assert_eq!(beer::verse(1), "1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n");
}
#[test]
#[ignore]
fn test_verse_2() {
assert_eq!(beer::verse(2), "2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n");
}
#[test]
#[ignore]
fn test_verse_8() {
assert_eq!(beer::verse(8), "8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n");
}
#[test]
#[ignore]
fn test_song_8_6() {
assert_eq!(beer::sing(8, 6), "8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n\n7 bottles of beer on the wall, 7 bottles of beer.\nTake one down and pass it around, 6 bottles of beer on the wall.\n\n6 bottles of beer on the wall, 6 bottles of beer.\nTake one down and pass it around, 5 bottles of beer on the wall.\n");
}
#[test]
#[ignore]
fn test_song_3_0() {
assert_eq!(beer::sing(3, 0), "3 bottles of beer on the wall, 3 bottles of beer.\nTake one down and pass it around, 2 bottles of beer on the wall.\n\n2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n\n1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n");
}

50
bob/.exercism/config.json Normal file
View File

@@ -0,0 +1,50 @@
{
"blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited.",
"authors": [
"EduardoBautista"
],
"contributors": [
"andrewclarkson",
"ashleygwilliams",
"austinlyons",
"cjmochrie",
"cmccandless",
"coriolinus",
"cwhakes",
"EduardoBautista",
"efx",
"ErikSchierboom",
"etrepum",
"f3rn0s",
"IanWhitney",
"kytrinyx",
"leoyvens",
"lewisclement",
"lutostag",
"mkantor",
"nfiles",
"petertseng",
"pminten",
"rofrol",
"rpottsoh",
"stefanv",
"stringparser",
"vvv",
"xakon",
"ZapAnton"
],
"files": {
"solution": [
"src/lib.rs",
"Cargo.toml"
],
"test": [
"tests/bob.rs"
],
"example": [
".meta/example.rs"
]
},
"source": "Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial.",
"source_url": "http://pine.fm/LearnToProgram/?Chapter=06"
}

View File

@@ -0,0 +1 @@
{"track":"rust","exercise":"bob","id":"2ba266860b29447aafa6e7938191d672","url":"https://exercism.org/tracks/rust/exercises/bob","handle":"ArthurDanjou","is_requester":true,"auto_approve":false}

8
bob/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
# Generated by Cargo
# will have compiled files and executables
/target/
**/*.rs.bk
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock

4
bob/Cargo.toml Normal file
View File

@@ -0,0 +1,4 @@
[package]
edition = "2021"
name = "bob"
version = "1.6.0"

85
bob/HELP.md Normal file
View File

@@ -0,0 +1,85 @@
# Help
## Running the tests
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 _only ignored_ tests without editing the tests source file, use:
```bash
$ cargo test -- --ignored
```
If you are using Rust 1.51 or later, you can run _all_ tests with
```bash
$ cargo test -- --include-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].
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
## Submitting your solution
You can submit your solution using the `exercism submit src/lib.rs Cargo.toml` 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 [Rust track's documentation](https://exercism.org/docs/tracks/rust)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
## Rust Installation
Refer to the [exercism help page][help-page] for Rust installation and learning
resources.
## 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 GitHub [track repository][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].
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
[help-page]: https://exercism.org/tracks/rust/learning
[github]: https://github.com/exercism/rust
[contribution guide]: https://exercism.org/docs/community/contributors

62
bob/README.md Normal file
View File

@@ -0,0 +1,62 @@
# Bob
Welcome to Bob on Exercism's Rust Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Bob is a lackadaisical teenager. In conversation, his responses are very limited.
Bob answers 'Sure.' if you ask him a question, such as "How are you?".
He answers 'Whoa, chill out!' if you YELL AT HIM (in all capitals).
He answers 'Calm down, I know what I'm doing!' if you yell a question at him.
He says 'Fine. Be that way!' if you address him without actually saying
anything.
He answers 'Whatever.' to anything else.
Bob's conversational partner is a purist when it comes to written communication and always follows normal rules regarding sentence punctuation in English.
## Source
### Created by
- @EduardoBautista
### Contributed to by
- @andrewclarkson
- @ashleygwilliams
- @austinlyons
- @cjmochrie
- @cmccandless
- @coriolinus
- @cwhakes
- @EduardoBautista
- @efx
- @ErikSchierboom
- @etrepum
- @f3rn0s
- @IanWhitney
- @kytrinyx
- @leoyvens
- @lewisclement
- @lutostag
- @mkantor
- @nfiles
- @petertseng
- @pminten
- @rofrol
- @rpottsoh
- @stefanv
- @stringparser
- @vvv
- @xakon
- @ZapAnton
### Based on
Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. - http://pine.fm/LearnToProgram/?Chapter=06

14
bob/src/lib.rs Normal file
View File

@@ -0,0 +1,14 @@
fn is_yelling(message: &str) -> bool {
let have_letters: bool = message.chars().filter(|c| c.is_alphabetic()).count() > 0;
message.to_uppercase() == message && have_letters
}
pub fn reply(message: &str) -> &str {
match message.trim() {
m if m.trim().len() == 0 => "Fine. Be that way!",
m if m.ends_with("?") && is_yelling(m) => "Calm down, I know what I'm doing!",
m if m.ends_with("?") => "Sure.",
m if is_yelling(m) => "Whoa, chill out!",
_ => "Whatever."
}
}

190
bob/tests/bob.rs Normal file
View File

@@ -0,0 +1,190 @@
fn process_response_case(phrase: &str, expected_response: &str) {
assert_eq!(bob::reply(phrase), expected_response);
}
#[test]
/// stating something
fn test_stating_something() {
process_response_case("Tom-ay-to, tom-aaaah-to.", "Whatever.");
}
#[test]
#[ignore]
/// ending with whitespace
fn test_ending_with_whitespace() {
process_response_case("Okay if like my spacebar quite a bit? ", "Sure.");
}
#[test]
#[ignore]
/// shouting numbers
fn test_shouting_numbers() {
process_response_case("1, 2, 3 GO!", "Whoa, chill out!");
}
#[test]
#[ignore]
/// other whitespace
fn test_other_whitespace() {
process_response_case("\r\r ", "Fine. Be that way!");
}
#[test]
#[ignore]
/// shouting with special characters
fn test_shouting_with_special_characters() {
process_response_case(
"ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!",
"Whoa, chill out!",
);
}
#[test]
#[ignore]
/// talking forcefully
fn test_talking_forcefully() {
process_response_case("Hi there!", "Whatever.");
}
#[test]
#[ignore]
/// prattling on
fn test_prattling_on() {
process_response_case("Wait! Hang on. Are you going to be OK?", "Sure.");
}
#[test]
#[ignore]
/// forceful question
fn test_forceful_question() {
process_response_case("WHAT'S GOING ON?", "Calm down, I know what I'm doing!");
}
#[test]
#[ignore]
/// shouting with no exclamation mark
fn test_shouting_with_no_exclamation_mark() {
process_response_case("I HATE THE DENTIST", "Whoa, chill out!");
}
#[test]
#[ignore]
/// asking gibberish
fn test_asking_gibberish() {
process_response_case("fffbbcbeab?", "Sure.");
}
#[test]
#[ignore]
/// question with no letters
fn test_question_with_no_letters() {
process_response_case("4?", "Sure.");
}
#[test]
#[ignore]
/// no letters
fn test_no_letters() {
process_response_case("1, 2, 3", "Whatever.");
}
#[test]
#[ignore]
/// statement containing question mark
fn test_statement_containing_question_mark() {
process_response_case("Ending with ? means a question.", "Whatever.");
}
//NEW
#[test]
#[ignore]
/// multiple line question
fn test_multiple_line_question() {
process_response_case(
"\rDoes this cryogenic chamber make me look fat?\rNo.",
"Whatever.",
);
}
#[test]
#[ignore]
/// non-question ending with whitespace
fn test_nonquestion_ending_with_whitespace() {
process_response_case(
"This is a statement ending with whitespace ",
"Whatever.",
);
}
#[test]
#[ignore]
/// shouting
fn test_shouting() {
process_response_case("WATCH OUT!", "Whoa, chill out!");
}
#[test]
#[ignore]
/// non-letters with question
fn test_nonletters_with_question() {
process_response_case(":) ?", "Sure.");
}
#[test]
#[ignore]
/// shouting gibberish
fn test_shouting_gibberish() {
process_response_case("FCECDFCAAB", "Whoa, chill out!");
}
#[test]
#[ignore]
/// asking a question
fn test_asking_a_question() {
process_response_case("Does this cryogenic chamber make me look fat?", "Sure.");
}
#[test]
#[ignore]
/// asking a numeric question
fn test_asking_a_numeric_question() {
process_response_case("You are, what, like 15?", "Sure.");
}
#[test]
#[ignore]
/// silence
fn test_silence() {
process_response_case("", "Fine. Be that way!");
}
#[test]
#[ignore]
/// starting with whitespace
fn test_starting_with_whitespace() {
process_response_case(" hmmmmmmm...", "Whatever.");
}
#[test]
#[ignore]
/// using acronyms in regular speech
fn test_using_acronyms_in_regular_speech() {
process_response_case(
"It's OK if you don't want to go work for NASA.",
"Whatever.",
);
}
#[test]
#[ignore]
/// alternate silence
fn test_alternate_silence() {
process_response_case(" ", "Fine. Be that way!");
}
#[test]
#[ignore]
/// prolonged silence
fn test_prolonged_silence() {
process_response_case(" ", "Fine. Be that way!");
}

View File

@@ -0,0 +1,43 @@
{
"blurb": "Implement a clock that handles times without dates.",
"authors": [
"sacherjj"
],
"contributors": [
"attilahorvath",
"coriolinus",
"cwhakes",
"danieljl",
"eddyp",
"efx",
"ErikSchierboom",
"felix91gr",
"kunaltyagi",
"lutostag",
"nfiles",
"petertseng",
"rofrol",
"shaaraddalvi",
"stringparser",
"tmccombs",
"xakon",
"ZapAnton"
],
"files": {
"solution": [
"src/lib.rs",
"Cargo.toml"
],
"test": [
"tests/clock.rs"
],
"example": [
".meta/example.rs"
]
},
"source": "Pairing session with Erin Drummond",
"source_url": "https://twitter.com/ebdrummond",
"custom": {
"allowed-to-not-compile": "Stub doesn't compile because there is no to_string() implementation. This exercise is an introduction to derived and self-implemented traits, therefore adding template for a trait would reduce student learning."
}
}

View File

@@ -0,0 +1 @@
{"track":"rust","exercise":"clock","id":"bcfb7c3bb06e42a0921d4975f51a864f","url":"https://exercism.org/tracks/rust/exercises/clock","handle":"ArthurDanjou","is_requester":true,"auto_approve":false}

8
clock/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
# Generated by Cargo
# will have compiled files and executables
/target/
**/*.rs.bk
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock

6
clock/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
edition = "2021"
name = "clock"
version = "2.4.0"
[dependencies]

85
clock/HELP.md Normal file
View File

@@ -0,0 +1,85 @@
# Help
## Running the tests
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 _only ignored_ tests without editing the tests source file, use:
```bash
$ cargo test -- --ignored
```
If you are using Rust 1.51 or later, you can run _all_ tests with
```bash
$ cargo test -- --include-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].
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
## Submitting your solution
You can submit your solution using the `exercism submit src/lib.rs Cargo.toml` 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 [Rust track's documentation](https://exercism.org/docs/tracks/rust)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
## Rust Installation
Refer to the [exercism help page][help-page] for Rust installation and learning
resources.
## 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 GitHub [track repository][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].
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
[help-page]: https://exercism.org/tracks/rust/learning
[github]: https://github.com/exercism/rust
[contribution guide]: https://exercism.org/docs/community/contributors

57
clock/README.md Normal file
View File

@@ -0,0 +1,57 @@
# Clock
Welcome to Clock on Exercism's Rust Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Implement a clock that handles times without dates.
You should be able to add and subtract minutes to it.
Two clocks that represent the same time should be equal to each other.
You will also need to implement `.to_string()` for the `Clock` struct. We will be using this to display the Clock's state. You can either do it via implementing it directly or using the [Display trait](https://doc.rust-lang.org/std/fmt/trait.Display.html).
Did you implement `.to_string()` for the `Clock` struct?
If so, try implementing the
[Display trait](https://doc.rust-lang.org/std/fmt/trait.Display.html) for `Clock` instead.
Traits allow for a common way to implement functionality for various types.
For additional learning, consider how you might implement `String::from` for the `Clock` type.
You don't have to actually implement this—it's redundant with `Display`, which is generally the
better choice when the destination type is `String`—but it's useful to have a few type-conversion
traits in your toolkit.
## Source
### Created by
- @sacherjj
### Contributed to by
- @attilahorvath
- @coriolinus
- @cwhakes
- @danieljl
- @eddyp
- @efx
- @ErikSchierboom
- @felix91gr
- @kunaltyagi
- @lutostag
- @nfiles
- @petertseng
- @rofrol
- @shaaraddalvi
- @stringparser
- @tmccombs
- @xakon
- @ZapAnton
### Based on
Pairing session with Erin Drummond - https://twitter.com/ebdrummond

39
clock/src/lib.rs Normal file
View File

@@ -0,0 +1,39 @@
#[derive(Eq, PartialEq, Debug)]
pub struct Clock {
minutes: i32,
}
const MINUTES_IN_AN_HOUR: i32 = 60;
const HOURS_IN_A_DAY: i32 = 24;
const MINUTES_IN_A_DAY: i32 = HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR;
impl ToString for Clock {
fn to_string(&self) -> String {
format!("{:02}:{:02}", self.hours(), self.minutes())
}
}
impl Clock {
pub fn new(hours: i32, minutes: i32) -> Self {
Self {
minutes: Self::as_minutes(hours, minutes),
}
}
pub fn add_minutes(&self, minutes: i32) -> Self {
Self::new(0, self.minutes + minutes)
}
fn as_minutes(hours: i32, minutes: i32) -> i32 {
((hours * MINUTES_IN_AN_HOUR + minutes) % MINUTES_IN_A_DAY + MINUTES_IN_A_DAY)
% MINUTES_IN_A_DAY
}
fn hours(&self) -> i32 {
self.minutes / MINUTES_IN_AN_HOUR
}
fn minutes(&self) -> i32 {
self.minutes % MINUTES_IN_AN_HOUR
}
}

352
clock/tests/clock.rs Normal file
View File

@@ -0,0 +1,352 @@
use clock::Clock;
//
// Clock Creation
//
#[test]
fn test_on_the_hour() {
assert_eq!(Clock::new(8, 0).to_string(), "08:00");
}
#[test]
#[ignore]
fn test_past_the_hour() {
assert_eq!(Clock::new(11, 9).to_string(), "11:09");
}
#[test]
#[ignore]
fn test_midnight_is_zero_hours() {
assert_eq!(Clock::new(24, 0).to_string(), "00:00");
}
#[test]
#[ignore]
fn test_hour_rolls_over() {
assert_eq!(Clock::new(25, 0).to_string(), "01:00");
}
#[test]
#[ignore]
fn test_hour_rolls_over_continuously() {
assert_eq!(Clock::new(100, 0).to_string(), "04:00");
}
#[test]
#[ignore]
fn test_sixty_minutes_is_next_hour() {
assert_eq!(Clock::new(1, 60).to_string(), "02:00");
}
#[test]
#[ignore]
fn test_minutes_roll_over() {
assert_eq!(Clock::new(0, 160).to_string(), "02:40");
}
#[test]
#[ignore]
fn test_minutes_roll_over_continuously() {
assert_eq!(Clock::new(0, 1723).to_string(), "04:43");
}
#[test]
#[ignore]
fn test_hours_and_minutes_roll_over() {
assert_eq!(Clock::new(25, 160).to_string(), "03:40");
}
#[test]
#[ignore]
fn test_hours_and_minutes_roll_over_continuously() {
assert_eq!(Clock::new(201, 3001).to_string(), "11:01");
}
#[test]
#[ignore]
fn test_hours_and_minutes_roll_over_to_exactly_midnight() {
assert_eq!(Clock::new(72, 8640).to_string(), "00:00");
}
#[test]
#[ignore]
fn test_negative_hour() {
assert_eq!(Clock::new(-1, 15).to_string(), "23:15");
}
#[test]
#[ignore]
fn test_negative_hour_roll_over() {
assert_eq!(Clock::new(-25, 00).to_string(), "23:00");
}
#[test]
#[ignore]
fn test_negative_hour_roll_over_continuously() {
assert_eq!(Clock::new(-91, 00).to_string(), "05:00");
}
#[test]
#[ignore]
fn test_negative_minutes() {
assert_eq!(Clock::new(1, -40).to_string(), "00:20");
}
#[test]
#[ignore]
fn test_negative_minutes_roll_over() {
assert_eq!(Clock::new(1, -160).to_string(), "22:20");
}
#[test]
#[ignore]
fn test_negative_minutes_roll_over_continuously() {
assert_eq!(Clock::new(1, -4820).to_string(), "16:40");
}
#[test]
#[ignore]
fn test_negative_sixty_minutes_is_prev_hour() {
assert_eq!(Clock::new(2, -60).to_string(), "01:00");
}
#[test]
#[ignore]
fn test_negative_one_twenty_minutes_is_two_prev_hours() {
assert_eq!(Clock::new(1, -120).to_string(), "23:00");
}
#[test]
#[ignore]
fn test_negative_hour_and_minutes_both_roll_over() {
assert_eq!(Clock::new(-25, -160).to_string(), "20:20");
}
#[test]
#[ignore]
fn test_negative_hour_and_minutes_both_roll_over_continuously() {
assert_eq!(Clock::new(-121, -5810).to_string(), "22:10");
}
#[test]
#[ignore]
fn test_zero_hour_and_negative_minutes() {
assert_eq!(Clock::new(0, -22).to_string(), "23:38");
}
//
// Clock Math
//
#[test]
#[ignore]
fn test_add_minutes() {
let clock = Clock::new(10, 0).add_minutes(3);
assert_eq!(clock.to_string(), "10:03");
}
#[test]
#[ignore]
fn test_add_no_minutes() {
let clock = Clock::new(6, 41).add_minutes(0);
assert_eq!(clock.to_string(), "06:41");
}
#[test]
#[ignore]
fn test_add_to_next_hour() {
let clock = Clock::new(0, 45).add_minutes(40);
assert_eq!(clock.to_string(), "01:25");
}
#[test]
#[ignore]
fn test_add_more_than_one_hour() {
let clock = Clock::new(10, 0).add_minutes(61);
assert_eq!(clock.to_string(), "11:01");
}
#[test]
#[ignore]
fn test_add_more_than_two_hours_with_carry() {
let clock = Clock::new(0, 45).add_minutes(160);
assert_eq!(clock.to_string(), "03:25");
}
#[test]
#[ignore]
fn test_add_across_midnight() {
let clock = Clock::new(23, 59).add_minutes(2);
assert_eq!(clock.to_string(), "00:01");
}
#[test]
#[ignore]
fn test_add_more_than_one_day() {
let clock = Clock::new(5, 32).add_minutes(1500);
assert_eq!(clock.to_string(), "06:32");
}
#[test]
#[ignore]
fn test_add_more_than_two_days() {
let clock = Clock::new(1, 1).add_minutes(3500);
assert_eq!(clock.to_string(), "11:21");
}
#[test]
#[ignore]
fn test_subtract_minutes() {
let clock = Clock::new(10, 3).add_minutes(-3);
assert_eq!(clock.to_string(), "10:00");
}
#[test]
#[ignore]
fn test_subtract_to_previous_hour() {
let clock = Clock::new(10, 3).add_minutes(-30);
assert_eq!(clock.to_string(), "09:33");
}
#[test]
#[ignore]
fn test_subtract_more_than_an_hour() {
let clock = Clock::new(10, 3).add_minutes(-70);
assert_eq!(clock.to_string(), "08:53");
}
#[test]
#[ignore]
fn test_subtract_across_midnight() {
let clock = Clock::new(0, 3).add_minutes(-4);
assert_eq!(clock.to_string(), "23:59");
}
#[test]
#[ignore]
fn test_subtract_more_than_two_hours() {
let clock = Clock::new(0, 0).add_minutes(-160);
assert_eq!(clock.to_string(), "21:20");
}
#[test]
#[ignore]
fn test_subtract_more_than_two_hours_with_borrow() {
let clock = Clock::new(6, 15).add_minutes(-160);
assert_eq!(clock.to_string(), "03:35");
}
#[test]
#[ignore]
fn test_subtract_more_than_one_day() {
let clock = Clock::new(5, 32).add_minutes(-1500);
assert_eq!(clock.to_string(), "04:32");
}
#[test]
#[ignore]
fn test_subtract_more_than_two_days() {
let clock = Clock::new(2, 20).add_minutes(-3000);
assert_eq!(clock.to_string(), "00:20");
}
//
// Test Equality
//
#[test]
#[ignore]
fn test_compare_clocks_for_equality() {
assert_eq!(Clock::new(15, 37), Clock::new(15, 37));
}
#[test]
#[ignore]
fn test_compare_clocks_a_minute_apart() {
assert_ne!(Clock::new(15, 36), Clock::new(15, 37));
}
#[test]
#[ignore]
fn test_compare_clocks_an_hour_apart() {
assert_ne!(Clock::new(14, 37), Clock::new(15, 37));
}
#[test]
#[ignore]
fn test_compare_clocks_with_hour_overflow() {
assert_eq!(Clock::new(10, 37), Clock::new(34, 37));
}
#[test]
#[ignore]
fn test_compare_clocks_with_hour_overflow_by_several_days() {
assert_eq!(Clock::new(99, 11), Clock::new(3, 11));
}
#[test]
#[ignore]
fn test_compare_clocks_with_negative_hour() {
assert_eq!(Clock::new(-2, 40), Clock::new(22, 40));
}
#[test]
#[ignore]
fn test_compare_clocks_with_negative_hour_that_wraps() {
assert_eq!(Clock::new(-31, 3), Clock::new(17, 3));
}
#[test]
#[ignore]
fn test_compare_clocks_with_negative_hour_that_wraps_multiple_times() {
assert_eq!(Clock::new(-83, 49), Clock::new(13, 49));
}
#[test]
#[ignore]
fn test_compare_clocks_with_minutes_overflow() {
assert_eq!(Clock::new(0, 1441), Clock::new(0, 1));
}
#[test]
#[ignore]
fn test_compare_clocks_with_minutes_overflow_by_several_days() {
assert_eq!(Clock::new(2, 4322), Clock::new(2, 2));
}
#[test]
#[ignore]
fn test_compare_clocks_with_negative_minute() {
assert_eq!(Clock::new(3, -20), Clock::new(2, 40));
}
#[test]
#[ignore]
fn test_compare_clocks_with_negative_minute_that_wraps() {
assert_eq!(Clock::new(5, -1490), Clock::new(4, 10));
}
#[test]
#[ignore]
fn test_compare_clocks_with_negative_minute_that_wraps_multiple() {
assert_eq!(Clock::new(6, -4305), Clock::new(6, 15));
}
#[test]
#[ignore]
fn test_compare_clocks_with_negative_hours_and_minutes() {
assert_eq!(Clock::new(-12, -268), Clock::new(7, 32));
}
#[test]
#[ignore]
fn test_compare_clocks_with_negative_hours_and_minutes_that_wrap() {
assert_eq!(Clock::new(-54, -11_513), Clock::new(18, 7));
}
#[test]
#[ignore]
fn test_compare_full_clock_and_zeroed_clock() {
assert_eq!(Clock::new(24, 0), Clock::new(0, 0));
}

View File

@@ -0,0 +1,45 @@
{
"blurb": "Given a moment, determine the moment that would be after a gigasecond has passed.",
"authors": [
"IanWhitney"
],
"contributors": [
"andy5995",
"ashleygwilliams",
"cbzehner",
"coriolinus",
"cwhakes",
"EduardoBautista",
"efx",
"ErikSchierboom",
"houhoulis",
"IanWhitney",
"janczer",
"leoyvens",
"lutostag",
"mkantor",
"nfiles",
"NieDzejkob",
"ocstl",
"petertseng",
"rofrol",
"sacherjj",
"stringparser",
"xakon",
"ZapAnton"
],
"files": {
"solution": [
"src/lib.rs",
"Cargo.toml"
],
"test": [
"tests/gigasecond.rs"
],
"example": [
".meta/example.rs"
]
},
"source": "Chapter 9 in Chris Pine's online Learn to Program tutorial.",
"source_url": "http://pine.fm/LearnToProgram/?Chapter=09"
}

View File

@@ -0,0 +1 @@
{"track":"rust","exercise":"gigasecond","id":"496981dcd7204a27be917dbc863f0a87","url":"https://exercism.org/tracks/rust/exercises/gigasecond","handle":"ArthurDanjou","is_requester":true,"auto_approve":false}

8
gigasecond/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
# Generated by Cargo
# will have compiled files and executables
/target/
**/*.rs.bk
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock

7
gigasecond/Cargo.toml Normal file
View File

@@ -0,0 +1,7 @@
[package]
edition = "2021"
name = "gigasecond"
version = "2.0.0"
[dependencies]
time = "0.3"

85
gigasecond/HELP.md Normal file
View File

@@ -0,0 +1,85 @@
# Help
## Running the tests
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 _only ignored_ tests without editing the tests source file, use:
```bash
$ cargo test -- --ignored
```
If you are using Rust 1.51 or later, you can run _all_ tests with
```bash
$ cargo test -- --include-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].
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
## Submitting your solution
You can submit your solution using the `exercism submit src/lib.rs Cargo.toml` 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 [Rust track's documentation](https://exercism.org/docs/tracks/rust)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
## Rust Installation
Refer to the [exercism help page][help-page] for Rust installation and learning
resources.
## 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 GitHub [track repository][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].
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
[help-page]: https://exercism.org/tracks/rust/learning
[github]: https://github.com/exercism/rust
[contribution guide]: https://exercism.org/docs/community/contributors

49
gigasecond/README.md Normal file
View File

@@ -0,0 +1,49 @@
# Gigasecond
Welcome to Gigasecond on Exercism's Rust Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Given a moment, determine the moment that would be after a gigasecond
has passed.
A gigasecond is 10^9 (1,000,000,000) seconds.
If you're unsure what operations you can perform on `PrimitiveDateTime` take a look at the [time crate](https://docs.rs/time) which is listed as a dependency in the `Cargo.toml` file for this exercise.
## Source
### Created by
- @IanWhitney
### Contributed to by
- @andy5995
- @ashleygwilliams
- @cbzehner
- @coriolinus
- @cwhakes
- @EduardoBautista
- @efx
- @ErikSchierboom
- @houhoulis
- @IanWhitney
- @janczer
- @leoyvens
- @lutostag
- @mkantor
- @nfiles
- @NieDzejkob
- @ocstl
- @petertseng
- @rofrol
- @sacherjj
- @stringparser
- @xakon
- @ZapAnton
### Based on
Chapter 9 in Chris Pine's online Learn to Program tutorial. - http://pine.fm/LearnToProgram/?Chapter=09

7
gigasecond/src/lib.rs Normal file
View File

@@ -0,0 +1,7 @@
use time::{Duration, PrimitiveDateTime as DateTime};
// Returns a DateTime one billion seconds after start.
pub fn after(start: DateTime) -> DateTime {
// Add 10 seconds to start
start + Duration::seconds(1_000_000_000)
}

View File

@@ -0,0 +1,52 @@
use time::PrimitiveDateTime as DateTime;
/// Create a datetime from the given numeric point in time.
///
/// Panics if any field is invalid.
fn dt(year: i32, month: u8, day: u8, hour: u8, minute: u8, second: u8) -> DateTime {
use time::{Date, Time};
DateTime::new(
Date::from_calendar_date(year, month.try_into().unwrap(), day).unwrap(),
Time::from_hms(hour, minute, second).unwrap(),
)
}
#[test]
fn test_date() {
let start_date = dt(2011, 4, 25, 0, 0, 0);
assert_eq!(gigasecond::after(start_date), dt(2043, 1, 1, 1, 46, 40));
}
#[test]
#[ignore]
fn test_another_date() {
let start_date = dt(1977, 6, 13, 0, 0, 0);
assert_eq!(gigasecond::after(start_date), dt(2009, 2, 19, 1, 46, 40));
}
#[test]
#[ignore]
fn test_third_date() {
let start_date = dt(1959, 7, 19, 0, 0, 0);
assert_eq!(gigasecond::after(start_date), dt(1991, 3, 27, 1, 46, 40));
}
#[test]
#[ignore]
fn test_datetime() {
let start_date = dt(2015, 1, 24, 22, 0, 0);
assert_eq!(gigasecond::after(start_date), dt(2046, 10, 2, 23, 46, 40));
}
#[test]
#[ignore]
fn test_another_datetime() {
let start_date = dt(2015, 1, 24, 23, 59, 59);
assert_eq!(gigasecond::after(start_date), dt(2046, 10, 3, 1, 46, 39));
}

View File

@@ -0,0 +1,43 @@
{
"blurb": "Given students' names along with the grade that they are in, create a roster for the school",
"authors": [
"EduardoBautista"
],
"contributors": [
"andrewclarkson",
"ashleygwilliams",
"coriolinus",
"cwhakes",
"EduardoBautista",
"efx",
"ErikSchierboom",
"ffflorian",
"IanWhitney",
"kytrinyx",
"lpil",
"lutostag",
"navossoc",
"nfiles",
"petertseng",
"pminten",
"rofrol",
"stevejb71",
"stringparser",
"xakon",
"ZapAnton"
],
"files": {
"solution": [
"src/lib.rs",
"Cargo.toml"
],
"test": [
"tests/grade-school.rs"
],
"example": [
".meta/example.rs"
]
},
"source": "A pairing session with Phil Battos at gSchool",
"source_url": "http://gschool.it"
}

View File

@@ -0,0 +1 @@
{"track":"rust","exercise":"grade-school","id":"5d0ccb19b5f0468d9f98154f1727365a","url":"https://exercism.org/tracks/rust/exercises/grade-school","handle":"ArthurDanjou","is_requester":true,"auto_approve":false}

8
grade-school/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
# Generated by Cargo
# will have compiled files and executables
/target/
**/*.rs.bk
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock

4
grade-school/Cargo.toml Normal file
View File

@@ -0,0 +1,4 @@
[package]
edition = "2021"
name = "grade-school"
version = "0.0.0"

85
grade-school/HELP.md Normal file
View File

@@ -0,0 +1,85 @@
# Help
## Running the tests
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 _only ignored_ tests without editing the tests source file, use:
```bash
$ cargo test -- --ignored
```
If you are using Rust 1.51 or later, you can run _all_ tests with
```bash
$ cargo test -- --include-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].
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
## Submitting your solution
You can submit your solution using the `exercism submit src/lib.rs Cargo.toml` 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 [Rust track's documentation](https://exercism.org/docs/tracks/rust)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
## Rust Installation
Refer to the [exercism help page][help-page] for Rust installation and learning
resources.
## 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 GitHub [track repository][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].
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
[help-page]: https://exercism.org/tracks/rust/learning
[github]: https://github.com/exercism/rust
[contribution guide]: https://exercism.org/docs/community/contributors

77
grade-school/README.md Normal file
View File

@@ -0,0 +1,77 @@
# Grade School
Welcome to Grade School on Exercism's Rust Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Given students' names along with the grade that they are in, create a roster
for the school.
In the end, you should be able to:
- Add a student's name to the roster for a grade
- "Add Jim to grade 2."
- "OK."
- Get a list of all students enrolled in a grade
- "Which students are in grade 2?"
- "We've only got Jim just now."
- Get a sorted list of all students in all grades. Grades should sort
as 1, 2, 3, etc., and students within a grade should be sorted
alphabetically by name.
- "Who all is enrolled in school right now?"
- "Let me think. We have
Anna, Barb, and Charlie in grade 1,
Alex, Peter, and Zoe in grade 2
and Jim in grade 5.
So the answer is: Anna, Barb, Charlie, Alex, Peter, Zoe and Jim"
Note that all our students only have one name. (It's a small town, what
do you want?)
## For bonus points
Did you get the tests passing and the code clean? If you want to, these
are some additional things you could try:
- If you're working in a language with mutable data structures and your
implementation allows outside code to mutate the school's internal DB
directly, see if you can prevent this. Feel free to introduce additional
tests.
Then please share your thoughts in a comment on the submission. Did this
experiment make the code better? Worse? Did you learn anything from it?
## Source
### Created by
- @EduardoBautista
### Contributed to by
- @andrewclarkson
- @ashleygwilliams
- @coriolinus
- @cwhakes
- @EduardoBautista
- @efx
- @ErikSchierboom
- @ffflorian
- @IanWhitney
- @kytrinyx
- @lpil
- @lutostag
- @navossoc
- @nfiles
- @petertseng
- @pminten
- @rofrol
- @stevejb71
- @stringparser
- @xakon
- @ZapAnton
### Based on
A pairing session with Phil Battos at gSchool - http://gschool.it

46
grade-school/src/lib.rs Normal file
View File

@@ -0,0 +1,46 @@
use std::collections::HashMap;
// This annotation prevents Clippy from warning us that `School` has a
// `fn new()` with no arguments, but doesn't implement the `Default` trait.
//
// Normally, it's good practice to just do what Clippy tells you, but in this
// case, we want to keep things relatively simple. The `Default` trait is not the point
// of this exercise.
#[allow(clippy::new_without_default)]
pub struct School {
student_grades: HashMap<u32, Vec<String>>
}
impl School {
pub fn new() -> Self {
Self {
student_grades: HashMap::new()
}
}
pub fn add(&mut self, grade: u32, student: &str) {
self.student_grades
.entry(grade)
.or_insert(Vec::new())
.push(student.to_owned())
}
pub fn grades(&self) -> Vec<u32> {
let mut grades = self.student_grades.keys().cloned().collect::<Vec<u32>>();
grades.sort();
grades
}
// If `grade` returned a reference, `School` would be forced to keep a `Vec<String>`
// internally to lend out. By returning an owned vector of owned `String`s instead,
// the internal structure can be completely arbitrary. The tradeoff is that some data
// must be copied each time `grade` is called.
pub fn grade(&self, grade: u32) -> Vec<String> {
let mut students_for_grade = match self.student_grades.get(&grade) {
Some(students_grade) => students_grade.to_vec(),
None => vec![]
};
students_for_grade.sort();
students_for_grade
}
}

View File

@@ -0,0 +1,83 @@
use grade_school as school;
fn to_owned(v: &[&str]) -> Vec<String> {
v.iter().map(|s| s.to_string()).collect()
}
#[test]
fn test_grades_for_empty_school() {
let s = school::School::new();
assert_eq!(s.grades(), vec![]);
}
#[test]
#[ignore]
fn test_grades_for_one_student() {
let mut s = school::School::new();
s.add(2, "Aimee");
assert_eq!(s.grades(), vec![2]);
}
#[test]
#[ignore]
fn test_grades_for_several_students_are_sorted() {
let mut s = school::School::new();
s.add(2, "Aimee");
s.add(7, "Logan");
s.add(4, "Blair");
assert_eq!(s.grades(), vec![2, 4, 7]);
}
#[test]
#[ignore]
fn test_grades_when_several_students_have_the_same_grade() {
let mut s = school::School::new();
s.add(2, "Aimee");
s.add(2, "Logan");
s.add(2, "Blair");
assert_eq!(s.grades(), vec![2]);
}
#[test]
#[ignore]
fn test_grade_for_empty_school() {
let s = school::School::new();
assert_eq!(s.grade(1), Vec::<String>::new());
}
#[test]
#[ignore]
fn test_grade_when_no_students_have_that_grade() {
let mut s = school::School::new();
s.add(7, "Logan");
assert_eq!(s.grade(1), Vec::<String>::new());
}
#[test]
#[ignore]
fn test_grade_for_one_student() {
let mut s = school::School::new();
s.add(2, "Aimee");
assert_eq!(s.grade(2), to_owned(&["Aimee"]));
}
#[test]
#[ignore]
fn test_grade_returns_students_sorted_by_name() {
let mut s = school::School::new();
s.add(2, "James");
s.add(2, "Blair");
s.add(2, "Paul");
assert_eq!(s.grade(2), to_owned(&["Blair", "James", "Paul"]));
}
#[test]
#[ignore]
fn test_add_students_to_different_grades() {
let mut s = school::School::new();
s.add(3, "Chelsea");
s.add(7, "Logan");
assert_eq!(s.grades(), vec![3, 7]);
assert_eq!(s.grade(3), to_owned(&["Chelsea"]));
assert_eq!(s.grade(7), to_owned(&["Logan"]));
}

View File

@@ -0,0 +1,18 @@
{
"blurb": "Learn structs to store statistics for a health-monitoring system.",
"authors": [
"seanchen1991"
],
"files": {
"solution": [
"src/lib.rs",
"Cargo.toml"
],
"test": [
"tests/health-statistics.rs"
],
"exemplar": [
".meta/exemplar.rs"
]
}
}

View File

@@ -0,0 +1 @@
{"track":"rust","exercise":"health-statistics","id":"f7698b2154ad4d28ba7ae9b85f9714c2","url":"https://exercism.org/tracks/rust/exercises/health-statistics","handle":"ArthurDanjou","is_requester":true,"auto_approve":false}

7
health-statistics/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "health_statistics"
version = "0.1.0"

View File

@@ -0,0 +1,4 @@
[package]
name = "health_statistics"
version = "0.1.0"
edition = "2021"

85
health-statistics/HELP.md Normal file
View File

@@ -0,0 +1,85 @@
# Help
## Running the tests
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 _only ignored_ tests without editing the tests source file, use:
```bash
$ cargo test -- --ignored
```
If you are using Rust 1.51 or later, you can run _all_ tests with
```bash
$ cargo test -- --include-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].
[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
## Submitting your solution
You can submit your solution using the `exercism submit src/lib.rs Cargo.toml` 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 [Rust track's documentation](https://exercism.org/docs/tracks/rust)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
## Rust Installation
Refer to the [exercism help page][help-page] for Rust installation and learning
resources.
## 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 GitHub [track repository][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].
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
[help-page]: https://exercism.org/tracks/rust/learning
[github]: https://github.com/exercism/rust
[contribution guide]: https://exercism.org/docs/community/contributors

View File

@@ -0,0 +1,31 @@
# Hints
## General
## 1. Implement the `new()` method
- The `new()` method receives the arguments we want to instantiate a `User` instance with. It should return an instance of `User` with the specified name, age, and weight.
- See [here](https://doc.rust-lang.org/book/ch05-01-defining-structs.html) for additional examples on defining and instantiating structs.
## 2. Implement the getter methods
- The `name()`, `age()`, and `weight()` methods are getters. In other words, they are responsible for returning the corresponding field from a struct instance.
- Notice that the `name` method returns a `&str` when the `name` field on the `User` struct is a `String`. How can we get `&str` and `String` to play nice with each other?
- There's no need to use a `return` statement in Rust unless you expressly want a function or method to return early. Otherwise, it's more idiomatic to utilize an _implicit_ return by omitting the semicolon for the result we want a function or method to return. It's not _wrong_ to use an explicit return, but it's cleaner to take advantage of implicit returns where possible.
```rust
fn foo() -> i32 {
1
}
```
- See [here](https://doc.rust-lang.org/book/ch05-03-method-syntax.html) for some more examples of defining methods on structs.
## 3. Implement the setter methods
- The `set_age()` and `set_weight()` methods are setters, responsible for updating the corresponding field on a struct instance with the input argument.
- As the signatures of these methods specify, the setter methods shouldn't return anything.

View File

@@ -0,0 +1,91 @@
# Health Statistics
Welcome to Health Statistics on Exercism's Rust Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
## Introduction
It is often useful to group a collection of items together, and handle those groups as units. In Rust, we call such a group a struct, and each item one of the struct's fields. A struct defines the general set of fields available, but a particular example of a struct is called an instance.
Furthermore, structs can have methods defined on them, which have access to the fields. The struct itself in that case is referred to as `self`. When a method uses `&mut self`, the fields can be changed, or mutated. When a method uses `&self`, the fields cannot be changed: they are immutable. Controlling mutability helps the borrow-checker ensure that entire classes of concurrency bug just don't happen in Rust.
In this exercise, you'll be implementing two kinds of methods on a struct. The first are generally known as getters: they expose the struct's fields to the world, without letting anyone else mutate that value. In Rust, these methods idiomatically share the name of the field they expose, i.e., if we have a getter method that fetches a struct field called `name`, the method would simply be called `name()`.
You'll also be implementing methods of another type, generally known as setters. These change the value of the field. Setters aren't very common in Rust--if a field can be freely modified, it is more common to just make it public--but they're useful if updating the field should have side effects, or for access control: a setter marked as `pub(crate)` allows other modules within the same crate to update a private field, which can't be affected by the outside world.
Structs come in three flavors: structs with named fields, tuple structs, and unit structs. For this concept exercise, we'll be exploring the first variant: structs with named fields.
Structs are defined using the `struct` keyword, followed by the capitalized name of the type the struct is describing:
```rust
struct Item {}
```
Additional types are then brought into the struct body as _fields_ of the struct, each with their own type:
```rust
struct Item {
name: String,
weight: f32,
worth: u32,
}
```
Lastly, methods can be defined on structs inside of an `impl` block:
```rust
impl Item {
// initializes and returns a new instance of our Item struct
fn new() -> Self {
unimplemented!()
}
}
```
With that brief introduction to the syntax of structs out of the way, go ahead and take a look at the [instructions](instructions.md) for this exercise!
## Instructions
You're working on implementing a health-monitoring system. As part of that, you need to keep track of users' health statistics.
You'll start with some stubbed functions in an `impl` block as well as the following struct definition:
```rust
pub struct User {
name: String,
age: u32,
weight: f32,
}
```
Your goal is to implement the stubbed out methods on the `User` `struct` defined in the `impl` block.
For example, the `new` method should return an instance of the `User` struct with the specified name, age, and weight values.
```rust
let mut bob = User::new(String::from("Bob"), 32, 155.2);
// Returns: a User with name "Bob", age 32, and weight 155.2
```
The `weight` method should return the weight of the `User`.
```rust
bob.weight();
// Returns: 155.2
```
The `set_age` method should set the age of the `User`.
```rust
bob.set_age(33);
// Updates Bob's age to 33; happy birthday Bob!
```
Have fun!
## Source
### Created by
- @seanchen1991

View File

@@ -0,0 +1,39 @@
// This stub file contains items that aren't used yet; feel free to remove this module attribute
// to enable stricter warnings.
#![allow(unused)]
pub struct User {
name: String,
age: u32,
weight: f32,
}
impl User {
pub fn new(name: String, age: u32, weight: f32) -> Self {
Self {
name,
age,
weight
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn age(&self) -> u32 {
self.age
}
pub fn weight(&self) -> f32 {
self.weight
}
pub fn set_age(&mut self, new_age: u32) {
self.age = new_age
}
pub fn set_weight(&mut self, new_weight: f32) {
self.weight = new_weight
}
}

View File

@@ -0,0 +1 @@
{"rustc_fingerprint":547482148007961314,"outputs":{"931469667778813386":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/arthurdanjou/.rustup/toolchains/stable-aarch64-apple-darwin\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"vh\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n","stderr":""},"17598535894874457435":{"success":true,"status":"","code":0,"stdout":"rustc 1.61.0 (fe5b13d68 2022-05-18)\nbinary: rustc\ncommit-hash: fe5b13d681f25ee6474be29d748c65adcd91f69e\ncommit-date: 2022-05-18\nhost: aarch64-apple-darwin\nrelease: 1.61.0\nLLVM version: 14.0.0\n","stderr":""},"2797684049618456168":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n","stderr":""}},"successes":{}}

View File

@@ -0,0 +1,3 @@
Signature: 8a477f597d28d172789f06886806bc55
# This file is a cache directory tag created by cargo.
# For information about cache directory tags see https://bford.info/cachedir/

View File

@@ -0,0 +1 @@
This file has an mtime of when this was started.

View File

@@ -0,0 +1 @@
{"rustc":5055087155190864114,"features":"[]","target":2579682610403781797,"profile":4734105543796642768,"path":2325082057379190229,"deps":[[12509414400136546036,"health_statistics",false,4812219169218510717]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/health_statistics-3855589a8de7cac3/dep-test-integration-test-health-statistics"}}],"rustflags":[],"metadata":7797948686568424061,"config":2202906307356721367,"compile_kind":0}

View File

@@ -0,0 +1 @@
This file has an mtime of when this was started.

View File

@@ -0,0 +1 @@
{"rustc":5055087155190864114,"features":"[]","target":5102910661884761124,"profile":11736316127369858332,"path":17523903030608720598,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/health_statistics-62e3af01ebef91c4/dep-lib-health_statistics"}}],"rustflags":[],"metadata":7797948686568424061,"config":2202906307356721367,"compile_kind":0}

View File

@@ -0,0 +1 @@
This file has an mtime of when this was started.

View File

@@ -0,0 +1 @@
{"rustc":5055087155190864114,"features":"[]","target":5102910661884761124,"profile":4734105543796642768,"path":17523903030608720598,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/health_statistics-786b473719522259/dep-test-lib-health_statistics"}}],"rustflags":[],"metadata":7797948686568424061,"config":2202906307356721367,"compile_kind":0}

Some files were not shown because too many files have changed in this diff Show More