From d3bfaf4131057a9156002516559e306541cf5cfb Mon Sep 17 00:00:00 2001 From: Rorik Star Platinum Date: Thu, 4 Dec 2025 17:27:34 +0300 Subject: [PATCH] space-age --- rust/space-age/.exercism/config.json | 40 +++++++++++ rust/space-age/.gitignore | 2 + rust/space-age/Cargo.toml | 9 +++ rust/space-age/HELP.md | 89 +++++++++++++++++++++++ rust/space-age/README.md | 102 +++++++++++++++++++++++++++ rust/space-age/src/lib.rs | 71 +++++++++++++++++++ rust/space-age/tests/space_age.rs | 81 +++++++++++++++++++++ 7 files changed, 394 insertions(+) create mode 100644 rust/space-age/.exercism/config.json create mode 100644 rust/space-age/.gitignore create mode 100644 rust/space-age/Cargo.toml create mode 100644 rust/space-age/HELP.md create mode 100644 rust/space-age/README.md create mode 100644 rust/space-age/src/lib.rs create mode 100644 rust/space-age/tests/space_age.rs diff --git a/rust/space-age/.exercism/config.json b/rust/space-age/.exercism/config.json new file mode 100644 index 0000000..193c33e --- /dev/null +++ b/rust/space-age/.exercism/config.json @@ -0,0 +1,40 @@ +{ + "authors": [ + "IanWhitney" + ], + "contributors": [ + "ashleygwilliams", + "bobahop", + "coriolinus", + "cwhakes", + "durka", + "eddyp", + "efx", + "ErikSchierboom", + "IanWhitney", + "joshgoebel", + "lutostag", + "nfiles", + "ocstl", + "petertseng", + "rofrol", + "stringparser", + "xakon", + "ZapAnton" + ], + "files": { + "solution": [ + "src/lib.rs", + "Cargo.toml" + ], + "test": [ + "tests/space_age.rs" + ], + "example": [ + ".meta/example.rs" + ] + }, + "blurb": "Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.", + "source": "Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial.", + "source_url": "https://pine.fm/LearnToProgram/?Chapter=01" +} diff --git a/rust/space-age/.gitignore b/rust/space-age/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/rust/space-age/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/rust/space-age/Cargo.toml b/rust/space-age/Cargo.toml new file mode 100644 index 0000000..bbe6044 --- /dev/null +++ b/rust/space-age/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "space_age" +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/space-age/HELP.md b/rust/space-age/HELP.md new file mode 100644 index 0000000..22a6c00 --- /dev/null +++ b/rust/space-age/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/space-age/README.md b/rust/space-age/README.md new file mode 100644 index 0000000..d602f23 --- /dev/null +++ b/rust/space-age/README.md @@ -0,0 +1,102 @@ +# Space Age + +Welcome to Space Age on Exercism's Rust Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Introduction + +The year is 2525 and you've just embarked on a journey to visit all planets in the Solar System (Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Neptune). +The first stop is Mercury, where customs require you to fill out a form (bureaucracy is apparently _not_ Earth-specific). +As you hand over the form to the customs officer, they scrutinize it and frown. +"Do you _really_ expect me to believe you're just 50 years old? +You must be closer to 200 years old!" + +Amused, you wait for the customs officer to start laughing, but they appear to be dead serious. +You realize that you've entered your age in _Earth years_, but the officer expected it in _Mercury years_! +As Mercury's orbital period around the sun is significantly shorter than Earth, you're actually a lot older in Mercury years. +After some quick calculations, you're able to provide your age in Mercury Years. +The customs officer smiles, satisfied, and waves you through. +You make a mental note to pre-calculate your planet-specific age _before_ future customs checks, to avoid such mix-ups. + +~~~~exercism/note +If you're wondering why Pluto didn't make the cut, go watch [this YouTube video][pluto-video]. + +[pluto-video]: https://www.youtube.com/watch?v=Z_2gbGXzFbs +~~~~ + +## Instructions + +Given an age in seconds, calculate how old someone would be on a planet in our Solar System. + +One Earth year equals 365.25 Earth days, or 31,557,600 seconds. +If you were told someone was 1,000,000,000 seconds old, their age would be 31.69 Earth-years. + +For the other planets, you have to account for their orbital period in Earth Years: + +| Planet | Orbital period in Earth Years | +| ------- | ----------------------------- | +| Mercury | 0.2408467 | +| Venus | 0.61519726 | +| Earth | 1.0 | +| Mars | 1.8808158 | +| Jupiter | 11.862615 | +| Saturn | 29.447498 | +| Uranus | 84.016846 | +| Neptune | 164.79132 | + +~~~~exercism/note +The actual length of one complete orbit of the Earth around the sun is closer to 365.256 days (1 sidereal year). +The Gregorian calendar has, on average, 365.2425 days. +While not entirely accurate, 365.25 is the value used in this exercise. +See [Year on Wikipedia][year] for more ways to measure a year. + +[year]: https://en.wikipedia.org/wiki/Year#Summary +~~~~ + +## Topics + +Some Rust topics you may want to read about while solving this problem: + +- Traits, both the From trait and [implementing your own traits](https://doc.rust-lang.org/book/ch10-02-traits.html) +- [Default method implementations](https://doc.rust-lang.org/book/ch10-02-traits.html#default-implementations) for traits +- Macros, the use of a macro could reduce boilerplate and increase readability + for this exercise. For instance, + [a macro can implement a trait for multiple types at once](https://stackoverflow.com/questions/39150216/implementing-a-trait-for-multiple-types-at-once), + though it is fine to implement `years_during` in the Planet trait itself. A macro could + define both the structs and their implementations. Info to get started with macros can + be found at: + + - [The Macros chapter in The Rust Programming Language](https://doc.rust-lang.org/stable/book/ch19-06-macros.html) + - [an older version of the Macros chapter with helpful detail](https://doc.rust-lang.org/1.30.0/book/first-edition/macros.html) + - [Rust By Example](https://doc.rust-lang.org/stable/rust-by-example/macros.html) + +## Source + +### Created by + +- @IanWhitney + +### Contributed to by + +- @ashleygwilliams +- @bobahop +- @coriolinus +- @cwhakes +- @durka +- @eddyp +- @efx +- @ErikSchierboom +- @IanWhitney +- @joshgoebel +- @lutostag +- @nfiles +- @ocstl +- @petertseng +- @rofrol +- @stringparser +- @xakon +- @ZapAnton + +### Based on + +Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial. - https://pine.fm/LearnToProgram/?Chapter=01 \ No newline at end of file diff --git a/rust/space-age/src/lib.rs b/rust/space-age/src/lib.rs new file mode 100644 index 0000000..3df9993 --- /dev/null +++ b/rust/space-age/src/lib.rs @@ -0,0 +1,71 @@ +// The code below is a stub. Just enough to satisfy the compiler. +// In order to pass the tests you can add-to or change any of this code. + +#[derive(Debug)] +pub struct Duration { + seconds: u64, +} + +impl From for Duration { + fn from(s: u64) -> Self { + Self { seconds: s } + } +} + +pub trait Planet { + fn years_during(d: &Duration) -> f64 { + (d.seconds as f64 / 60.0 / 60.0 / 24.0) / 365.25 / Self::period() + } + fn period() -> f64; +} + +pub struct Mercury; +pub struct Venus; +pub struct Earth; +pub struct Mars; +pub struct Jupiter; +pub struct Saturn; +pub struct Uranus; +pub struct Neptune; + +impl Planet for Mercury { + fn period() -> f64 { + 0.2408467 + } +} +impl Planet for Venus { + fn period() -> f64 { + 0.61519726 + } +} +impl Planet for Earth { + fn period() -> f64 { + 1.0 + } +} + +impl Planet for Mars { + fn period() -> f64 { + 1.8808158 + } +} +impl Planet for Jupiter { + fn period() -> f64 { + 11.862615 + } +} +impl Planet for Saturn { + fn period() -> f64 { + 29.447498 + } +} +impl Planet for Uranus { + fn period() -> f64 { + 84.016846 + } +} +impl Planet for Neptune { + fn period() -> f64 { + 164.79132 + } +} diff --git a/rust/space-age/tests/space_age.rs b/rust/space-age/tests/space_age.rs new file mode 100644 index 0000000..deff9e2 --- /dev/null +++ b/rust/space-age/tests/space_age.rs @@ -0,0 +1,81 @@ +use space_age::*; + +fn assert_in_delta(expected: f64, actual: f64) { + let diff: f64 = (expected - actual).abs(); + let delta: f64 = 0.01; + if diff > delta { + panic!("Your result of {actual} should be within {delta} of the expected result {expected}") + } +} + +#[test] +fn age_on_earth() { + let seconds = 1_000_000_000; + let duration = Duration::from(seconds); + let output = Earth::years_during(&duration); + let expected = 31.69; + assert_in_delta(expected, output); +} + +#[test] +fn age_on_mercury() { + let seconds = 2_134_835_688; + let duration = Duration::from(seconds); + let output = Mercury::years_during(&duration); + let expected = 280.88; + assert_in_delta(expected, output); +} + +#[test] +fn age_on_venus() { + let seconds = 189_839_836; + let duration = Duration::from(seconds); + let output = Venus::years_during(&duration); + let expected = 9.78; + assert_in_delta(expected, output); +} + +#[test] +fn age_on_mars() { + let seconds = 2_129_871_239; + let duration = Duration::from(seconds); + let output = Mars::years_during(&duration); + let expected = 35.88; + assert_in_delta(expected, output); +} + +#[test] +fn age_on_jupiter() { + let seconds = 901_876_382; + let duration = Duration::from(seconds); + let output = Jupiter::years_during(&duration); + let expected = 2.41; + assert_in_delta(expected, output); +} + +#[test] +fn age_on_saturn() { + let seconds = 2_000_000_000; + let duration = Duration::from(seconds); + let output = Saturn::years_during(&duration); + let expected = 2.15; + assert_in_delta(expected, output); +} + +#[test] +fn age_on_uranus() { + let seconds = 1_210_123_456; + let duration = Duration::from(seconds); + let output = Uranus::years_during(&duration); + let expected = 0.46; + assert_in_delta(expected, output); +} + +#[test] +fn age_on_neptune() { + let seconds = 1_821_023_456; + let duration = Duration::from(seconds); + let output = Neptune::years_during(&duration); + let expected = 0.35; + assert_in_delta(expected, output); +}