diff --git a/rust/flower-field/.exercism/config.json b/rust/flower-field/.exercism/config.json new file mode 100644 index 0000000..aa8cb9c --- /dev/null +++ b/rust/flower-field/.exercism/config.json @@ -0,0 +1,39 @@ +{ + "authors": [ + "EduardoBautista" + ], + "contributors": [ + "ashleygwilliams", + "coriolinus", + "cwhakes", + "EduardoBautista", + "efx", + "ErikSchierboom", + "ffflorian", + "IanWhitney", + "keiravillekode", + "kytrinyx", + "lutostag", + "mkantor", + "nfiles", + "petertseng", + "rofrol", + "stringparser", + "workingjubilee", + "xakon", + "ZapAnton" + ], + "files": { + "solution": [ + "src/lib.rs", + "Cargo.toml" + ], + "test": [ + "tests/flower_field.rs" + ], + "example": [ + ".meta/example.rs" + ] + }, + "blurb": "Mark all the flowers in a garden." +} diff --git a/rust/flower-field/.gitignore b/rust/flower-field/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/rust/flower-field/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/rust/flower-field/Cargo.toml b/rust/flower-field/Cargo.toml new file mode 100644 index 0000000..fc11c06 --- /dev/null +++ b/rust/flower-field/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "flower_field" +version = "0.1.0" +edition = "2024" + +# Not all libraries from crates.io are available in Exercism's test runner. +# The full list of available libraries is here: +# https://github.com/exercism/rust-test-runner/blob/main/local-registry/Cargo.toml +[dependencies] diff --git a/rust/flower-field/HELP.md b/rust/flower-field/HELP.md new file mode 100644 index 0000000..22a6c00 --- /dev/null +++ b/rust/flower-field/HELP.md @@ -0,0 +1,89 @@ +# 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) +- The [Rust track's programming category on the forum](https://forum.exercism.org/c/programming/rust) +- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5) +- 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 + +Head to [the forum](https://forum.exercism.org/c/programming/rust/) and create a post to provide feedback about an exercise or if you want to help implement new exercises. +Members of the rust track team are happy to help! + +The GitHub [track repository][github] is the home for all of the Rust exercises. + +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 \ No newline at end of file diff --git a/rust/flower-field/README.md b/rust/flower-field/README.md new file mode 100644 index 0000000..3686286 --- /dev/null +++ b/rust/flower-field/README.md @@ -0,0 +1,76 @@ +# Flower Field + +Welcome to Flower Field on Exercism's Rust Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Introduction + +[Flower Field][history] is a compassionate reimagining of the popular game Minesweeper. +The object of the game is to find all the flowers in the garden using numeric hints that indicate how many flowers are directly adjacent (horizontally, vertically, diagonally) to a square. +"Flower Field" shipped in regional versions of Microsoft Windows in Italy, Germany, South Korea, Japan and Taiwan. + +[history]: https://web.archive.org/web/20020409051321fw_/http://rcm.usr.dsi.unimi.it/rcmweb/fnm/ + +## Instructions + +Your task is to add flower counts to empty squares in a completed Flower Field garden. +The garden itself is a rectangle board composed of squares that are either empty (`' '`) or a flower (`'*'`). + +For each empty square, count the number of flowers adjacent to it (horizontally, vertically, diagonally). +If the empty square has no adjacent flowers, leave it empty. +Otherwise replace it with the count of adjacent flowers. + +For example, you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen): + +```text +·*·*· +··*·· +··*·· +····· +``` + +Which your code should transform into this: + +```text +1*3*1 +13*31 +·2*2· +·111· +``` + +## Performance Hint + +All the inputs and outputs are in ASCII. +Rust `String`s and `&str` are utf8, so while one might expect `"Hello".chars()` to be simple, it actually has to check each char to see if it's 1, 2, 3 or 4 `u8`s long. +If we know a `&str` is ASCII then we can call `.as_bytes()` and refer to the underlying data as a `&[u8]` (byte slice). +Iterating over a slice of ASCII bytes is much quicker as there are no codepoints involved - every ASCII byte is one `u8` long. + +Can you complete the challenge without cloning the input? + +## Source + +### Created by + +- @EduardoBautista + +### Contributed to by + +- @ashleygwilliams +- @coriolinus +- @cwhakes +- @EduardoBautista +- @efx +- @ErikSchierboom +- @ffflorian +- @IanWhitney +- @keiravillekode +- @kytrinyx +- @lutostag +- @mkantor +- @nfiles +- @petertseng +- @rofrol +- @stringparser +- @workingjubilee +- @xakon +- @ZapAnton \ No newline at end of file diff --git a/rust/flower-field/src/lib.rs b/rust/flower-field/src/lib.rs new file mode 100644 index 0000000..965fb2b --- /dev/null +++ b/rust/flower-field/src/lib.rs @@ -0,0 +1,5 @@ +pub fn annotate(garden: &[&str]) -> Vec { + todo!( + "\nAnnotate each square of the given garden with the number of flowers that surround said square (blank if there are no surrounding flowers):\n{garden:#?}\n" + ); +} diff --git a/rust/flower-field/tests/flower_field.rs b/rust/flower-field/tests/flower_field.rs new file mode 100644 index 0000000..e356b35 --- /dev/null +++ b/rust/flower-field/tests/flower_field.rs @@ -0,0 +1,199 @@ +use flower_field::*; + +#[test] +fn no_rows() { + let input = &[]; + let expected: &[&str] = &[]; + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn no_columns() { + let input = &[""]; + let expected = &[""]; + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn no_flowers() { + #[rustfmt::skip] + let (input, expected) = (&[ + " ", + " ", + " ", + ], &[ + " ", + " ", + " ", + ]); + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn garden_full_of_flowers() { + #[rustfmt::skip] + let (input, expected) = (&[ + "***", + "***", + "***", + ], &[ + "***", + "***", + "***", + ]); + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn flower_surrounded_by_spaces() { + #[rustfmt::skip] + let (input, expected) = (&[ + " ", + " * ", + " ", + ], &[ + "111", + "1*1", + "111", + ]); + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn space_surrounded_by_flowers() { + #[rustfmt::skip] + let (input, expected) = (&[ + "***", + "* *", + "***", + ], &[ + "***", + "*8*", + "***", + ]); + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn horizontal_line() { + let input = &[" * * "]; + let expected = &["1*2*1"]; + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn horizontal_line_flowers_at_edges() { + let input = &["* *"]; + let expected = &["*1 1*"]; + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn vertical_line() { + #[rustfmt::skip] + let (input, expected) = (&[ + " ", + "*", + " ", + "*", + " ", + ], &[ + "1", + "*", + "2", + "*", + "1", + ]); + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn vertical_line_flowers_at_edges() { + #[rustfmt::skip] + let (input, expected) = (&[ + "*", + " ", + " ", + " ", + "*", + ], &[ + "*", + "1", + " ", + "1", + "*", + ]); + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn cross() { + #[rustfmt::skip] + let (input, expected) = (&[ + " * ", + " * ", + "*****", + " * ", + " * ", + ], &[ + " 2*2 ", + "25*52", + "*****", + "25*52", + " 2*2 ", + ]); + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn large_garden() { + #[rustfmt::skip] + let (input, expected) = (&[ + " * * ", + " * ", + " * ", + " * *", + " * * ", + " ", + ], &[ + "1*22*1", + "12*322", + " 123*2", + "112*4*", + "1*22*2", + "111111", + ]); + let actual = annotate(input); + assert_eq!(actual, expected); +} + +#[test] +#[ignore] +fn multiple_adjacent_flowers() { + let input = &[" ** "]; + let expected = &["1**1"]; + let actual = annotate(input); + assert_eq!(actual, expected); +}