diff --git a/config.json b/config.json index bfc5127..ef05e54 100644 --- a/config.json +++ b/config.json @@ -68,7 +68,6 @@ "difficulty": 1 }, { -<<<<<<< HEAD "slug": "collatz-conjecture", "name": "Collatz Conjecture", "uuid": "d87d43a6-91c0-4a60-a54e-86b86050436b", @@ -107,6 +106,14 @@ "practices": [], "prerequisites": [], "difficulty": 1 + }, + { + "slug": "space-age", + "name": "Space Age", + "uuid": "2e4aeee6-e53d-409f-9eaa-67ca4daabc55", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, diff --git a/exercises/practice/space-age/.docs/instructions.md b/exercises/practice/space-age/.docs/instructions.md new file mode 100644 index 0000000..f23b5e2 --- /dev/null +++ b/exercises/practice/space-age/.docs/instructions.md @@ -0,0 +1,28 @@ +# 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 +~~~~ diff --git a/exercises/practice/space-age/.docs/introduction.md b/exercises/practice/space-age/.docs/introduction.md new file mode 100644 index 0000000..014d788 --- /dev/null +++ b/exercises/practice/space-age/.docs/introduction.md @@ -0,0 +1,20 @@ +# 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 +~~~~ diff --git a/exercises/practice/space-age/.meta/config.json b/exercises/practice/space-age/.meta/config.json new file mode 100644 index 0000000..b8a3c6f --- /dev/null +++ b/exercises/practice/space-age/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "gvrooyen" + ], + "files": { + "solution": [ + "space_age.odin" + ], + "test": [ + "space_age_test.odin" + ], + "example": [ + ".meta/space_age_example.odin" + ] + }, + "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/exercises/practice/space-age/.meta/space_age_example.odin b/exercises/practice/space-age/.meta/space_age_example.odin new file mode 100644 index 0000000..2dcfb6b --- /dev/null +++ b/exercises/practice/space-age/.meta/space_age_example.odin @@ -0,0 +1,29 @@ +package space_age + +Planet :: enum { + Mercury, + Venus, + Earth, + Mars, + Jupiter, + Saturn, + Uranus, + Neptune, +} + +period := map[Planet]f64 { + .Mercury = 0.2408467, + .Venus = 0.61519726, + .Earth = 1.0, + .Mars = 1.8808158, + .Jupiter = 11.862615, + .Saturn = 29.447498, + .Uranus = 84.016846, + .Neptune = 164.79132, +} + +seconds_per_earth_year :: 31_557_600 + +age :: proc(planet: Planet, seconds: int) -> f64 { + return f64(seconds) / seconds_per_earth_year / period[planet] +} diff --git a/exercises/practice/space-age/.meta/tests.toml b/exercises/practice/space-age/.meta/tests.toml new file mode 100644 index 0000000..7957bb7 --- /dev/null +++ b/exercises/practice/space-age/.meta/tests.toml @@ -0,0 +1,37 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[84f609af-5a91-4d68-90a3-9e32d8a5cd34] +description = "age on Earth" + +[ca20c4e9-6054-458c-9312-79679ffab40b] +description = "age on Mercury" + +[502c6529-fd1b-41d3-8fab-65e03082b024] +description = "age on Venus" + +[9ceadf5e-a0d5-4388-9d40-2c459227ceb8] +description = "age on Mars" + +[42927dc3-fe5e-4f76-a5b5-f737fc19bcde] +description = "age on Jupiter" + +[8469b332-7837-4ada-b27c-00ee043ebcad] +description = "age on Saturn" + +[999354c1-76f8-4bb5-a672-f317b6436743] +description = "age on Uranus" + +[80096d30-a0d4-4449-903e-a381178355d8] +description = "age on Neptune" + +[57b96e2a-1178-40b7-b34d-f3c9c34e4bf4] +description = "invalid planet causes error" diff --git a/exercises/practice/space-age/space_age.odin b/exercises/practice/space-age/space_age.odin new file mode 100644 index 0000000..a4fb3ba --- /dev/null +++ b/exercises/practice/space-age/space_age.odin @@ -0,0 +1,16 @@ +package space_age + +Planet :: enum { + Mercury, + Venus, + Earth, + Mars, + Jupiter, + Saturn, + Uranus, + Neptune, +} + +age :: proc(planet: Planet, seconds: int) -> f64 { + #panic("Please implement the `age` procedure.") +} diff --git a/exercises/practice/space-age/space_age_test.odin b/exercises/practice/space-age/space_age_test.odin new file mode 100644 index 0000000..df4d24f --- /dev/null +++ b/exercises/practice/space-age/space_age_test.odin @@ -0,0 +1,62 @@ +/* These are the unit tests for the exercise. Only the first one is enabled to start with. You can + * enable the other tests by uncommenting the `@(test)` attribute of the test procedure. Your + * solution should pass all tests before it is ready for submission. + */ + +package space_age + +import "base:intrinsics" +import "core:log" +import "core:testing" + +expect_almost :: proc( + value, expected: $T, + tolerance := 0.01, + loc := #caller_location, +) -> bool where intrinsics.type_is_float(T) { + ok := abs(expected - value) <= tolerance + if !ok { + log.errorf("expected %.2f, got %.2f", expected, value, location = loc) + } + return ok +} + +@(test) +test_age_on_earth :: proc(t: ^testing.T) { + expect_almost(age(.Earth, 1_000_000_000), 31.69) +} + +// @(test) +test_age_on_mercury :: proc(t: ^testing.T) { + expect_almost(age(.Mercury, 2_134_835_688), 280.88) +} + +// @(test) +test_age_on_venus :: proc(t: ^testing.T) { + expect_almost(age(.Venus, 189_839_836), 9.78) +} + +// @(test) +test_age_on_mars :: proc(t: ^testing.T) { + expect_almost(age(.Mars, 2_129_871_239), 35.88) +} + +// @(test) +test_age_on_jupiter :: proc(t: ^testing.T) { + expect_almost(age(.Jupiter, 901_876_382), 2.41) +} + +// @(test) +test_age_on_saturn :: proc(t: ^testing.T) { + expect_almost(age(.Saturn, 2_000_000_000), 2.15) +} + +// @(test) +test_age_on_uranus :: proc(t: ^testing.T) { + expect_almost(age(.Uranus, 1_210_123_456), 0.46) +} + +// @(test) +test_age_on_neptune :: proc(t: ^testing.T) { + expect_almost(age(.Neptune, 1_821_023_456), 0.35) +}