Skip to content

Instantly share code, notes, and snippets.

@laracasts
Created December 15, 2019 18:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laracasts/a3c375b8b977fc71b2dcd200f49a7776 to your computer and use it in GitHub Desktop.
Save laracasts/a3c375b8b977fc71b2dcd200f49a7776 to your computer and use it in GitHub Desktop.
Roman numerals Kata
<?php
namespace App;
class RomanNumerals
{
const NUMERALS = [
'M' => 1000,
'CM' => 900,
'D' => 500,
'CD' => 400,
'C' => 100,
'XC' => 90,
'L' => 50,
'XL' => 40,
'X' => 10,
'IX' => 9,
'V' => 5,
'IV' => 4,
'I' => 1
];
public static function generate(int $number)
{
if ($number <= 0 || $number >= 4000) {
return false;
}
$result = '';
foreach (static::NUMERALS as $numeral => $arabic) {
for (; $number >= $arabic; $number -= $arabic) {
$result .= $numeral;
}
}
return $result;
}
}
<?php
use App\RomanNumerals;
use PHPUnit\Framework\TestCase;
class RomanNumeralsTest extends TestCase
{
/**
* @test
* @dataProvider checks
*/
function it_generates_roman_numerals($number, $numeral)
{
$this->assertEquals($numeral, RomanNumerals::generate($number));
}
/** @test */
function it_cannot_generate_a_roman_numeral_for_less_than_1()
{
$this->assertFalse(RomanNumerals::generate(0));
}
/** @test */
function it_cannot_generate_a_roman_numeral_for_more_than_3999()
{
$this->assertFalse(RomanNumerals::generate(4000));
}
public function checks()
{
return [
[1, 'I'],
[2, 'II'],
[3, 'III'],
[4, 'IV'],
[5, 'V'],
[6, 'VI'],
[7, 'VII'],
[8, 'VIII'],
[9, 'IX'],
[10, 'X'],
[40, 'XL'],
[50, 'L'],
[90, 'XC'],
[100, 'C'],
[400, 'CD'],
[500, 'D'],
[900, 'CM'],
[1000, 'M'],
[3999, 'MMMCMXCIX']
];
}
}
@tomasnorre
Copy link

I think it defeats the purpose of the Kata, but saw this elegant solution on exercism.org :)

<?php

function toRoman(int $number): string
{
    // Cf. https://www.php.net/manual/de/class.numberformatter.php
    // and https://github.com/unicode-org/icu/blob/master/icu4c/source/data/misc/numberingSystems.txt

    return (new NumberFormatter('@numbers=roman', NumberFormatter::DECIMAL))
        ->format($number);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment