Browse Source

04 Roman numerals.

Frédéric G. MARAND 2 months ago
parent
commit
e83b708b98

+ 27 - 0
roman-numerals/.exercism/config.json

@@ -0,0 +1,27 @@
+{
+  "authors": [],
+  "contributors": [
+    "arueckauer",
+    "dkinzer",
+    "Dog",
+    "kunicmarko20",
+    "kytrinyx",
+    "lafent",
+    "petemcfarlane",
+    "zembrowski"
+  ],
+  "files": {
+    "solution": [
+      "RomanNumerals.php"
+    ],
+    "test": [
+      "RomanNumeralsTest.php"
+    ],
+    "example": [
+      ".meta/example.php"
+    ]
+  },
+  "blurb": "Write a function to convert from normal numbers to Roman Numerals.",
+  "source": "The Roman Numeral Kata",
+  "source_url": "https://codingdojo.org/kata/RomanNumerals"
+}

+ 1 - 0
roman-numerals/.exercism/metadata.json

@@ -0,0 +1 @@
+{"track":"php","exercise":"roman-numerals","id":"660fc8e6dba2451f98e67641b8b03cc9","url":"https://exercism.org/tracks/php/exercises/roman-numerals","handle":"Fairgame","is_requester":true,"auto_approve":false}

+ 52 - 0
roman-numerals/HELP.md

@@ -0,0 +1,52 @@
+# Help
+
+## Running the tests
+
+## Running the tests
+
+1. Go to the root of your PHP exercise directory, which is `<EXERCISM_WORKSPACE>/php`.
+   To find the Exercism workspace run
+
+       ➜ exercism debug | grep Workspace
+
+1. Get [PHPUnit] if you don't have it already.
+
+       ➜ wget -O phpunit https://phar.phpunit.de/phpunit-9.phar
+       ➜ chmod +x phpunit
+       ➜ ./phpunit --version
+
+2. Execute the tests:
+
+       ➜ ./phpunit file_to_test.php
+
+   For example, to run the tests for the Hello World exercise, you would run:
+
+       ➜ ./phpunit HelloWorldTest.php
+
+[PHPUnit]: https://phpunit.de
+
+## Submitting your solution
+
+You can submit your solution using the `exercism submit RomanNumerals.php` 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 [PHP track's documentation](https://exercism.org/docs/tracks/php)
+- The [PHP track's programming category on the forum](https://forum.exercism.org/c/programming/php)
+- [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.
+
+To get help if you're having trouble, you can use one of the following resources:
+
+ - [/r/php](https://www.reddit.com/r/php) is the PHP subreddit.
+ - [StackOverflow](https://stackoverflow.com/questions/tagged/php) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

+ 65 - 0
roman-numerals/README.md

@@ -0,0 +1,65 @@
+# Roman Numerals
+
+Welcome to Roman Numerals on Exercism's PHP Track.
+If you need help running the tests or submitting your code, check out `HELP.md`.
+
+## Instructions
+
+Write a function to convert from normal numbers to Roman Numerals.
+
+The Romans were a clever bunch. They conquered most of Europe and ruled
+it for hundreds of years. They invented concrete and straight roads and
+even bikinis. One thing they never discovered though was the number
+zero. This made writing and dating extensive histories of their exploits
+slightly more challenging, but the system of numbers they came up with
+is still in use today. For example the BBC uses Roman numerals to date
+their programmes.
+
+The Romans wrote numbers using letters - I, V, X, L, C, D, M. (notice
+these letters have lots of straight lines and are hence easy to hack
+into stone tablets).
+
+```text
+ 1  => I
+10  => X
+ 7  => VII
+```
+
+There is no need to be able to convert numbers larger than about 3000.
+(The Romans themselves didn't tend to go any higher)
+
+Wikipedia says: Modern Roman numerals ... are written by expressing each
+digit separately starting with the left most digit and skipping any
+digit with a value of zero.
+
+To see this in practice, consider the example of 1990.
+
+In Roman numerals 1990 is MCMXC:
+
+1000=M
+900=CM
+90=XC
+
+2008 is written as MMVIII:
+
+2000=MM
+8=VIII
+
+See also: https://www.novaroma.org/via_romana/numbers.html
+
+## Source
+
+### Contributed to by
+
+- @arueckauer
+- @dkinzer
+- @Dog
+- @kunicmarko20
+- @kytrinyx
+- @lafent
+- @petemcfarlane
+- @zembrowski
+
+### Based on
+
+The Roman Numeral Kata - https://codingdojo.org/kata/RomanNumerals

+ 64 - 0
roman-numerals/RomanNumerals.php

@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * By adding type hints and enabling strict type checking, code can become
+ * easier to read, self-documenting and reduce the number of potential bugs.
+ * By default, type declarations are non-strict, which means they will attempt
+ * to change the original type to match the type specified by the
+ * type-declaration.
+ *
+ * In other words, if you pass a string to a function requiring a float,
+ * it will attempt to convert the string value to a float.
+ *
+ * To enable strict mode, a single declare directive must be placed at the top
+ * of the file.
+ * This means that the strictness of typing is configured on a per-file basis.
+ * This directive not only affects the type declarations of parameters, but also
+ * a function's return type.
+ *
+ * For more info review the Concept on strict type checking in the PHP track
+ * <link>.
+ *
+ * To disable strict typing, comment out the directive below.
+ */
+
+declare(strict_types=1);
+
+class mapping
+{
+    public int $n;
+    public string $lit;
+
+    public function __construct(int $n, string $lit)
+    {
+        $this->n = $n;
+        $this->lit = $lit;
+    }
+}
+
+function toRoman(int $number): string
+{
+    $literals = [
+        new mapping(10_00, "M"),
+        new mapping(9_00, "CM"),
+        new mapping(5_00, "D"),
+        new mapping(4_00, "CD"),
+        new mapping(1_00, "C"),
+        new mapping(90, "XC"),
+        new mapping(50, "L"),
+        new mapping(40, "XL"),
+        new mapping(10, "X"),
+        new mapping(9, "IX"),
+        new mapping(5, "V"),
+        new mapping(4, "IV"),
+        new mapping(1, "I"),
+    ];
+    $roman = "";
+    foreach ($literals as $mapping) {
+        while ($number >= $mapping->n) {
+            $roman .= $mapping->lit;
+            $number -= $mapping->n;
+        }
+    }
+    return $roman;
+}

+ 138 - 0
roman-numerals/RomanNumeralsTest.php

@@ -0,0 +1,138 @@
+<?php
+
+/*
+ * By adding type hints and enabling strict type checking, code can become
+ * easier to read, self-documenting and reduce the number of potential bugs.
+ * By default, type declarations are non-strict, which means they will attempt
+ * to change the original type to match the type specified by the
+ * type-declaration.
+ *
+ * In other words, if you pass a string to a function requiring a float,
+ * it will attempt to convert the string value to a float.
+ *
+ * To enable strict mode, a single declare directive must be placed at the top
+ * of the file.
+ * This means that the strictness of typing is configured on a per-file basis.
+ * This directive not only affects the type declarations of parameters, but also
+ * a function's return type.
+ *
+ * For more info review the Concept on strict type checking in the PHP track
+ * <link>.
+ *
+ * To disable strict typing, comment out the directive below.
+ */
+
+declare(strict_types=1);
+
+class RomanNumeralsTest extends PHPUnit\Framework\TestCase
+{
+    public static function setUpBeforeClass(): void
+    {
+        require_once 'RomanNumerals.php';
+    }
+
+    public function test1(): void
+    {
+        $this->assertSame('I', toRoman(1));
+    }
+
+    public function test2(): void
+    {
+        $this->assertSame('II', toRoman(2));
+    }
+
+    public function test3(): void
+    {
+        $this->assertSame('III', toRoman(3));
+    }
+
+    public function test4(): void
+    {
+        $this->assertSame('IV', toRoman(4));
+    }
+
+    public function test5(): void
+    {
+        $this->assertSame('V', toRoman(5));
+    }
+
+    public function test6(): void
+    {
+        $this->assertSame('VI', toRoman(6));
+    }
+
+    public function test9(): void
+    {
+        $this->assertSame('IX', toRoman(9));
+    }
+
+    public function test27(): void
+    {
+        $this->assertSame('XXVII', toRoman(27));
+    }
+
+    public function test48(): void
+    {
+        $this->assertSame('XLVIII', toRoman(48));
+    }
+
+    public function test49(): void
+    {
+        $this->assertSame('XLIX', toRoman(49));
+    }
+
+    public function test59(): void
+    {
+        $this->assertSame('LIX', toRoman(59));
+    }
+
+    public function test93(): void
+    {
+        $this->assertSame('XCIII', toRoman(93));
+    }
+
+    public function test141(): void
+    {
+        $this->assertSame('CXLI', toRoman(141));
+    }
+
+    public function test163(): void
+    {
+        $this->assertSame('CLXIII', toRoman(163));
+    }
+
+    public function test402(): void
+    {
+        $this->assertSame('CDII', toRoman(402));
+    }
+
+    public function test575(): void
+    {
+        $this->assertSame('DLXXV', toRoman(575));
+    }
+
+    public function test911(): void
+    {
+        $this->assertSame('CMXI', toRoman(911));
+    }
+
+    public function test1024(): void
+    {
+        $this->assertSame('MXXIV', toRoman(1024));
+    }
+
+    public function test1998(): void
+    {
+        $this->assertSame('MCMXCVIII', toRoman(1998));
+    }
+
+    public function test2999(): void
+    {
+        $this->assertSame('MMCMXCIX', toRoman(2999));
+    }
+
+    public function test3000(): void
+    {
+        $this->assertSame('MMM', toRoman(3000));
+    }
+}