Browse Source

Exercism: Magazine Cutout

master
Julio Biason 3 years ago
parent
commit
d462fdb585
  1. 17
      rust/magazine-cutout/.exercism/config.json
  2. 1
      rust/magazine-cutout/.exercism/metadata.json
  3. 7
      rust/magazine-cutout/Cargo.lock
  4. 5
      rust/magazine-cutout/Cargo.toml
  5. 85
      rust/magazine-cutout/HELP.md
  6. 17
      rust/magazine-cutout/HINTS.md
  7. 44
      rust/magazine-cutout/README.md
  8. 31
      rust/magazine-cutout/src/lib.rs
  9. 60
      rust/magazine-cutout/tests/magazine-cutout.rs

17
rust/magazine-cutout/.exercism/config.json

@ -0,0 +1,17 @@
{
"blurb": "Use `HashMap` and the entry API methods to write an anonymous letter.",
"authors": [
"seanchen1991"
],
"files": {
"solution": [
"src/lib.rs"
],
"test": [
"tests/magazine-cutout.rs"
],
"exemplar": [
".meta/exemplar.rs"
]
}
}

1
rust/magazine-cutout/.exercism/metadata.json

@ -0,0 +1 @@
{"track":"rust","exercise":"magazine-cutout","id":"02f9f776d0cc4b4d90efeea84020a57c","url":"https://exercism.org/tracks/rust/exercises/magazine-cutout","handle":"JBiason","is_requester":true,"auto_approve":false}

7
rust/magazine-cutout/Cargo.lock generated

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

5
rust/magazine-cutout/Cargo.toml

@ -0,0 +1,5 @@
[package]
name = "magazine_cutout"
version = "0.1.0"
edition = "2018"

85
rust/magazine-cutout/HELP.md

@ -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` 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.io/tracks/rust/learning
[github]: https://github.com/exercism/rust
[contribution guide]: https://exercism.io/docs/community/contributors

17
rust/magazine-cutout/HINTS.md

@ -0,0 +1,17 @@
# Hints
## General
- Upon fetching an entry using the `entry` method, the entry can be modified in-place after dereferencing it.
- The `or_insert` [method](https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.or_insert) inserts the given value in the case when the entry is vacant, and returns a mutable reference to the value in the entry.
```rust
*counter.entry(key).or_insert(0) += 1;
```
- The `or_default` [method](https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.or_default) ensures a value is in the entry by inserting the default value if empty, and returns a mutable reference to the value in the entry.
```rust
*counter.entry(key).or_default() += 1;
```

44
rust/magazine-cutout/README.md

@ -0,0 +1,44 @@
# Magazine Cutout
Welcome to Magazine Cutout 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
Rust's entry API provides a view into a single entry in map, which may be either a `HashMap` or a `BTreeMap`. The entry may be either occupied and vacant, and the API provides methods to modify the contents of the entry.
## Instructions
In this exercise you'll be using a `HashMap`, along with entry API methods, to solve a simple algorithm problem.
Given `&[&str]` representing the words of a magazine article, and `&[&str]` representing the words of a note you would like to send, can you compose your note by cutting words out of the magazine and pasting them into a letter?
Notes:
- This implies physical cutting and pasting; the magazine needs to contain at least as many copies of each word as the note requires.
- Capitalization matters; just because you're pasting together a note composed from words of a magazine doesn't mean you're willing to be ungrammatical.
You'll start with the following stubbed function signature:
```rust
pub fn can_construct_note(magazine: &[&str], note: &[&str]) -> bool {
unimplemented!()
}
```
Given the following input
```rust
let magazine = "two times three is not four".split_whitespace().collect::<Vec<&str>>();
let note = "two times two is four".split_whitespace().collect::<Vec<&str>>();
assert!(!can_construct_note(&magazine, &note));
```
The function returns `false` since the magazine only contains one instance of `"two"` when the note requires two of them.
## Source
### Created by
- @seanchen1991

31
rust/magazine-cutout/src/lib.rs

@ -0,0 +1,31 @@
// This stub file contains items which aren't used yet; feel free to remove this module attribute
// to enable stricter warnings.
#![allow(unused)]
use std::collections::HashMap;
pub fn can_construct_note(magazine: &[&str], note: &[&str]) -> bool {
let mut words_on_magazine: HashMap<&str, u16> = HashMap::new();
magazine.iter().for_each(|word| {
let count = if words_on_magazine.contains_key(word) {
*words_on_magazine.get(word).unwrap()
} else {
0
};
words_on_magazine.insert(word, count + 1);
});
for note_word in note {
if !words_on_magazine.contains_key(note_word) {
return false;
} else {
let count = words_on_magazine.get(note_word).unwrap() - 1;
if count > 0 {
words_on_magazine.insert(note_word, count);
} else {
words_on_magazine.remove(note_word);
}
}
}
true
}

60
rust/magazine-cutout/tests/magazine-cutout.rs

@ -0,0 +1,60 @@
use magazine_cutout::*;
#[test]
fn test_example_works() {
let magazine = "two times three is not four"
.split_whitespace()
.collect::<Vec<&str>>();
let note = "two times two is four"
.split_whitespace()
.collect::<Vec<&str>>();
assert!(!can_construct_note(&magazine, &note));
}
#[test]
fn test_fn_returns_true_for_good_input() {
let magazine = "The metro orchestra unveiled its new grand piano today. Its donor paraphrased Nathn Hale: \"I only regret that I have but one to give \"".split_whitespace().collect::<Vec<&str>>();
let note = "give one grand today."
.split_whitespace()
.collect::<Vec<&str>>();
assert!(can_construct_note(&magazine, &note));
}
#[test]
fn test_fn_returns_false_for_bad_input() {
let magazine = "I've got a lovely bunch of coconuts."
.split_whitespace()
.collect::<Vec<&str>>();
let note = "I've got som coconuts"
.split_whitespace()
.collect::<Vec<&str>>();
assert!(!can_construct_note(&magazine, &note));
}
#[test]
fn test_case_sensitivity() {
let magazine = "i've got some lovely coconuts"
.split_whitespace()
.collect::<Vec<&str>>();
let note = "I've got some coconuts"
.split_whitespace()
.collect::<Vec<&str>>();
assert!(!can_construct_note(&magazine, &note));
let magazine = "I've got some lovely coconuts"
.split_whitespace()
.collect::<Vec<&str>>();
let note = "i've got some coconuts"
.split_whitespace()
.collect::<Vec<&str>>();
assert!(!can_construct_note(&magazine, &note));
}
#[test]
fn test_magzine_has_more_than_words_available_than_needed() {
let magazine = "Enough is enough when enough is enough"
.split_whitespace()
.collect::<Vec<&str>>();
let note = "enough is enough".split_whitespace().collect::<Vec<&str>>();
assert!(can_construct_note(&magazine, &note));
}
Loading…
Cancel
Save