From 5d83ad66f0900d686367c5654b294f953f1c80f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?=
 <20251272+BNAndras@users.noreply.github.com>
Date: Fri, 8 Mar 2024 23:01:19 -0800
Subject: [PATCH] Add space-age

---
 config.json                                   |  8 +++
 .../practice/space-age/.docs/instructions.md  | 25 ++++++++
 .../practice/space-age/.meta/config.json      | 19 ++++++
 exercises/practice/space-age/.meta/tests.toml | 38 ++++++++++++
 exercises/practice/space-age/dub.sdl          |  2 +
 .../practice/space-age/example/space_age.d    | 55 +++++++++++++++++
 .../practice/space-age/source/space-age.d     | 59 +++++++++++++++++++
 7 files changed, 206 insertions(+)
 create mode 100644 exercises/practice/space-age/.docs/instructions.md
 create mode 100644 exercises/practice/space-age/.meta/config.json
 create mode 100644 exercises/practice/space-age/.meta/tests.toml
 create mode 100644 exercises/practice/space-age/dub.sdl
 create mode 100644 exercises/practice/space-age/example/space_age.d
 create mode 100644 exercises/practice/space-age/source/space-age.d

diff --git a/config.json b/config.json
index 0a75c92..0da0a36 100644
--- a/config.json
+++ b/config.json
@@ -472,6 +472,14 @@
         "practices": [],
         "prerequisites": [],
         "difficulty": 2
+      },
+      {
+        "slug": "space-age",
+        "name": "Space Age",
+        "uuid": "4f4b13d8-b92e-4cfe-ae7f-b3a6e398a421",
+        "practices": [],
+        "prerequisites": [],
+        "difficulty": 2
       }
     ]
   },
diff --git a/exercises/practice/space-age/.docs/instructions.md b/exercises/practice/space-age/.docs/instructions.md
new file mode 100644
index 0000000..fe938cc
--- /dev/null
+++ b/exercises/practice/space-age/.docs/instructions.md
@@ -0,0 +1,25 @@
+# Instructions
+
+Given an age in seconds, calculate how old someone would be on:
+
+- Mercury: orbital period 0.2408467 Earth years
+- Venus: orbital period 0.61519726 Earth years
+- Earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31557600 seconds
+- Mars: orbital period 1.8808158 Earth years
+- Jupiter: orbital period 11.862615 Earth years
+- Saturn: orbital period 29.447498 Earth years
+- Uranus: orbital period 84.016846 Earth years
+- Neptune: orbital period 164.79132 Earth years
+
+So if you were told someone were 1,000,000,000 seconds old, you should
+be able to say that they're 31.69 Earth-years old.
+
+If you're wondering why Pluto didn't make the cut, go watch [this YouTube video][pluto-video].
+
+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.
+
+[pluto-video]: https://www.youtube.com/watch?v=Z_2gbGXzFbs
+[year]: https://en.wikipedia.org/wiki/Year#Summary
diff --git a/exercises/practice/space-age/.meta/config.json b/exercises/practice/space-age/.meta/config.json
new file mode 100644
index 0000000..d032e0b
--- /dev/null
+++ b/exercises/practice/space-age/.meta/config.json
@@ -0,0 +1,19 @@
+{
+  "authors": [
+    "BNAndras"
+  ],
+  "files": {
+    "solution": [
+      "source/space_age.d"
+    ],
+    "test": [
+      "source/space_age.d"
+    ],
+    "example": [
+      "example/space_age.d"
+    ]
+  },
+  "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/tests.toml b/exercises/practice/space-age/.meta/tests.toml
new file mode 100644
index 0000000..a62017e
--- /dev/null
+++ b/exercises/practice/space-age/.meta/tests.toml
@@ -0,0 +1,38 @@
+# 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"
+include = false
diff --git a/exercises/practice/space-age/dub.sdl b/exercises/practice/space-age/dub.sdl
new file mode 100644
index 0000000..1547b89
--- /dev/null
+++ b/exercises/practice/space-age/dub.sdl
@@ -0,0 +1,2 @@
+name "space-age"
+buildRequirements "disallowDeprecations"
diff --git a/exercises/practice/space-age/example/space_age.d b/exercises/practice/space-age/example/space_age.d
new file mode 100644
index 0000000..dac7fc9
--- /dev/null
+++ b/exercises/practice/space-age/example/space_age.d
@@ -0,0 +1,55 @@
+module space_age;
+
+class SpaceAge
+{
+    public:
+
+        this(immutable long seconds)
+        {
+            this.seconds = seconds;
+        }
+
+        final float on_earth() const
+        {
+            return this.seconds / this.seconds_in_year;
+        }
+
+        final float on_mercury() const
+        {
+            return this.on_earth() / 0.240846;
+        }
+        
+        final float on_venus() const
+        {
+            return this.on_earth() / 0.61519726;
+        }
+        
+        final float on_mars() const
+        {
+            return this.on_earth() / 1.8808158;
+        }
+        
+        final float on_jupiter() const
+        {
+            return this.on_earth() / 11.862615;
+        }
+        
+        final float on_saturn() const
+        {
+            return this.on_earth() / 29.447498;
+        }
+        
+        final float on_uranus() const
+        {
+            return this.on_earth() / 84.016846;
+        }
+        
+        final float on_neptune() const
+        {
+            return this.on_earth() / 164.79132;
+        }
+
+    private:
+        immutable float seconds_in_year = 31_557_600;
+        immutable long seconds;
+}
\ No newline at end of file
diff --git a/exercises/practice/space-age/source/space-age.d b/exercises/practice/space-age/source/space-age.d
new file mode 100644
index 0000000..a288ed3
--- /dev/null
+++ b/exercises/practice/space-age/source/space-age.d
@@ -0,0 +1,59 @@
+module space_age;
+
+unittest
+{
+    import std.math : approxEqual;
+    immutable int allTestsEnabled = 0;
+
+    // Age on Earth
+    {
+        const SpaceAge age = new SpaceAge(1_000_000_000);
+        assert(age.on_earth().approxEqual(31.69));
+    }
+
+    static if (allTestsEnabled)
+    {
+        // Age on Mercury
+        {
+            const SpaceAge age = new SpaceAge(2_134_835_688);
+            assert(age.on_mercury().approxEqual(280.88));
+        }
+
+        // Age on Venus
+        {
+            const SpaceAge age = new SpaceAge(189_839_836);
+            assert(age.on_venus().approxEqual(9.78));
+        }
+
+        // Age on Mars
+        {
+            const SpaceAge age = new SpaceAge(2_129_871_239);
+            assert(age.on_mars().approxEqual(35.88));
+        }
+
+        // Age on Jupiter
+        {
+            const SpaceAge age = new SpaceAge(901_876_382);
+            assert(age.on_jupiter().approxEqual(2.41));
+        }
+
+        // Age on Saturn
+        {
+            const SpaceAge age = new SpaceAge(2_000_000_000);
+            assert(age.on_saturn().approxEqual(2.15));
+        }
+
+        // Age on Uranus
+        {
+            const SpaceAge age = new SpaceAge(1_210_123_456);
+            assert(age.on_uranus().approxEqual(0.46));
+        }
+
+        // Age on Neptune
+        {
+            const SpaceAge age = new SpaceAge(1_821_023_456);
+            assert(age.on_neptune().approxEqual(0.35));
+        }
+    }
+
+}