<?php
namespace JoshDiFabio;
interface RomanNumeralGeneratorInterface
{
/**
* @param int $number
* @return string
* @throws \InvalidArgumentException Argument not an integer or out of range
* @author Josh Di Fabio <joshdifabio@hotmail.com>
*/
public function generate($number);
}
class RomanNumeral
{
const ONE = 'I';
const FIVE = 'V';
const TEN = 'X';
const FIFTY = 'L';
const ONE_HUNDRED = 'C';
const FIVE_HUNDRED = 'D';
const ONE_THOUSAND = 'M';
}
class RomanNumeralGenerator implements RomanNumeralGeneratorInterface
{
/**
* @var array
* @author Josh Di Fabio <joshdifabio@hotmail.com>
*/
private $_numerals = array(
array(
'integer' => 1000,
'symbol' => RomanNumeral::ONE_THOUSAND,
),
array(
'integer' => 500,
'symbol' => RomanNumeral::FIVE_HUNDRED,
),
array(
'integer' => 100,
'symbol' => RomanNumeral::ONE_HUNDRED,
),
array(
'integer' => 50,
'symbol' => RomanNumeral::FIFTY,
),
array(
'integer' => 10,
'symbol' => RomanNumeral::TEN,
),
array(
'integer' => 5,
'symbol' => RomanNumeral::FIVE,
),
array(
'integer' => 1,
'symbol' => RomanNumeral::ONE,
),
);
/**
* @param int $number
* @return string
* @throws \InvalidArgumentException Argument not an integer or out of range
* @author Josh Di Fabio <joshdifabio@hotmail.com>
*/
public function generate($number)
{
if (!is_integer($number)) {
throw new \InvalidArgumentException('Provided argument is not an integer.');
}
if (1 > $number || 3999 < $number) {
throw new \InvalidArgumentException(
'The provided number is not within the allowed range of 1 to 3999.');
}
$numerals = array();
while (0 < $number) {
// loop through numerals from largest to smallest
foreach ($this->_numerals as $_numeralIdx => &$_numeralData) {
/*
* if the input number less any already selected numerals is larger than the current
* numeral, choose the current numeral and deduct its integer value from the input
* number
*/
if ($number >= $_numeralData['integer']) {
$numerals[] = $_numeralData['symbol'];
$number -= $_numeralData['integer'];
break;
}
for ($_lesserNumIdx = 1 + $_numeralIdx; 0 <= $_lesserNumIdx; $_lesserNumIdx--) {
$_lesserNumeralData = $this->_numerals[$_lesserNumIdx];
if ($number >= $_numeralData['integer'] - $_lesserNumeralData['integer']) {
$numerals[] = $_lesserNumeralData['symbol'];
$numerals[] = $_numeralData['symbol'];
$number -= ($_numeralData['integer'] - $_lesserNumeralData['integer']);
break(2);
}
}
}
}
return implode('', $numerals);
}
}
$generator = new RomanNumeralGenerator;
echo $generator->generate(3999);
Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 67108872 bytes) in /in/H1iKY on line 99
Process exited with code 255.
Output for 8.2.0 - 8.2.17, 8.3.0 - 8.3.4
Fatal error: Out of memory (allocated 18878464 bytes) (tried to allocate 33554440 bytes) in /in/H1iKY on line 99
mmap() failed: [12] Cannot allocate memory
mmap() failed: [12] Cannot allocate memory
Process exited with code 255.
Output for 8.1.2 - 8.1.27
Fatal error: Out of memory (allocated 18878464) (tried to allocate 33554440 bytes) in /in/H1iKY on line 99
mmap() failed: [12] Cannot allocate memory
mmap() failed: [12] Cannot allocate memory
Process exited with code 255.
Output for 7.3.32 - 7.3.33, 7.4.26, 8.0.13
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 134217736 bytes) in /in/H1iKY on line 99
Process exited with code 255.
Output for 5.4.0 - 5.4.9, 5.6.7 - 5.6.28
Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 72 bytes) in /in/H1iKY on line 98
Process exited with code 255.
Output for 5.4.10 - 5.4.45, 5.5.24 - 5.5.35
Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 72 bytes) in /in/H1iKY on line 99
Process exited with code 255.
Output for 5.3.11 - 5.3.29
Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 71 bytes) in /in/H1iKY on line 99
Process exited with code 255.
Output for 5.3.0 - 5.3.10
Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 71 bytes) in /in/H1iKY on line 98
Process exited with code 255.