3v4l.org

run code in 300+ PHP versions simultaneously
<?php namespace JoshDiFabio; /* * Note that I have included the interface and both concrete classes in a single file purely to * simplify the process of distributing and reviewing the code. Ordinarily I would use a separate * file for each class according to PSR-0 and use an autoloader to load them. * * This implementation assumes the following integer => numeral mappings which might not always be * considered implicit: 4 => IV, 9 => IX, 40 => XL, 90 => XC, 400 => CD, 900 => CM. This is because, * according to Wikipedia, I can precede V and X, X can precede L and C, etc. * * I have assumed that the rules of Roman Numerals are static; hence the fast, graceful but fairly * inflexible (in the sense that it can't be configured) solution. * * Requires PHP >= 5.3.0 */ 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 defining basic rules of roman numerals */ class RomanNumeral { const ONE = 'I'; const FOUR = 'IV'; const FIVE = 'V'; const NINE = 'IX'; const TEN = 'X'; const FOURTY = 'XL'; const FIFTY = 'L'; const NINETY = 'XC'; const ONE_HUNDRED = 'C'; const FOUR_HUNDRED = 'CD'; const FIVE_HUNDRED = 'D'; const NINE_HUNDRED = 'CM'; const ONE_THOUSAND = 'M'; /** * @return array * @author Josh Di Fabio <joshdifabio@hotmail.com> */ public static function getIntegerToNumeralMap() { return array( 1 => self::ONE, 4 => self::FOUR, 5 => self::FIVE, 9 => self::NINE, 10 => self::TEN, 40 => self::FOURTY, 50 => self::FIFTY, 90 => self::NINETY, 100 => self::ONE_HUNDRED, 400 => self::FOUR_HUNDRED, 500 => self::FIVE_HUNDRED, 900 => self::NINE_HUNDRED, 1000 => self::ONE_THOUSAND, ); } } /** * Class for generating roman numeral strings based on integers */ class RomanNumeralGenerator implements RomanNumeralGeneratorInterface { /** * @param int $inputNumber * @return string * @throws \InvalidArgumentException Argument not an integer or out of range * @author Josh Di Fabio <joshdifabio@hotmail.com> */ public function generate($inputNumber) { if (!is_integer($inputNumber)) { throw new \InvalidArgumentException('Provided argument is not an integer.'); } if (1 > $inputNumber || 3999 < $inputNumber) { throw new \InvalidArgumentException( 'The provided number is not within the allowed range of 1 to 3999.'); } $numeralString = ''; // get integer to numeral map and sort from largest to smallest $integerToNumeralMap = RomanNumeral::getIntegerToNumeralMap(); krsort($integerToNumeralMap); while (0 < $inputNumber) { foreach ($integerToNumeralMap as $_numeralAsInteger => $_numeral) { /* * if input number minus any already selected numerals is larger than the current * numeral, select the current numeral and deduct its integer value from the input * number */ if ($inputNumber >= $_numeralAsInteger) { /* * append matching numeral to output string and deduct its integer value from * input number */ $numeralString .= $_numeral; $inputNumber -= $_numeralAsInteger; break; } } } return $numeralString; } } $generator = new RomanNumeralGenerator; echo $generator->generate(3999);
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/OntJH
function name:  (null)
number of ops:  9
compiled vars:  !0 = $generator
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   76     0  E >   DECLARE_CLASS                                            'joshdifabio%5Cromannumeralgenerator'
  123     1        NEW                                              $1      'JoshDiFabio%5CRomanNumeralGenerator'
          2        DO_FCALL                                      0          
          3        ASSIGN                                                   !0, $1
  124     4        INIT_METHOD_CALL                                         !0, 'generate'
          5        SEND_VAL_EX                                              3999
          6        DO_FCALL                                      0  $4      
          7        ECHO                                                     $4
          8      > RETURN                                                   1

Class JoshDiFabio\RomanNumeralGeneratorInterface:
Function generate:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/OntJH
function name:  generate
number of ops:  2
compiled vars:  !0 = $number
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   27     0  E >   RECV                                             !0      
          1      > RETURN                                                   null

End of function generate

End of class JoshDiFabio\RomanNumeralGeneratorInterface.

Class JoshDiFabio\RomanNumeral:
Function getintegertonumeralmap:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/OntJH
function name:  getIntegerToNumeralMap
number of ops:  28
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   56     0  E >   FETCH_CLASS_CONSTANT                             ~0      'ONE'
          1        INIT_ARRAY                                       ~1      ~0, 1
   57     2        FETCH_CLASS_CONSTANT                             ~2      'FOUR'
          3        ADD_ARRAY_ELEMENT                                ~1      ~2, 4
   58     4        FETCH_CLASS_CONSTANT                             ~3      'FIVE'
          5        ADD_ARRAY_ELEMENT                                ~1      ~3, 5
   59     6        FETCH_CLASS_CONSTANT                             ~4      'NINE'
          7        ADD_ARRAY_ELEMENT                                ~1      ~4, 9
   60     8        FETCH_CLASS_CONSTANT                             ~5      'TEN'
          9        ADD_ARRAY_ELEMENT                                ~1      ~5, 10
   61    10        FETCH_CLASS_CONSTANT                             ~6      'FOURTY'
         11        ADD_ARRAY_ELEMENT                                ~1      ~6, 40
   62    12        FETCH_CLASS_CONSTANT                             ~7      'FIFTY'
         13        ADD_ARRAY_ELEMENT                                ~1      ~7, 50
   63    14        FETCH_CLASS_CONSTANT                             ~8      'NINETY'
         15        ADD_ARRAY_ELEMENT                                ~1      ~8, 90
   64    16        FETCH_CLASS_CONSTANT                             ~9      'ONE_HUNDRED'
         17        ADD_ARRAY_ELEMENT                                ~1      ~9, 100
   65    18        FETCH_CLASS_CONSTANT                             ~10     'FOUR_HUNDRED'
         19        ADD_ARRAY_ELEMENT                                ~1      ~10, 400
   66    20        FETCH_CLASS_CONSTANT                             ~11     'FIVE_HUNDRED'
         21        ADD_ARRAY_ELEMENT                                ~1      ~11, 500
   67    22        FETCH_CLASS_CONSTANT                             ~12     'NINE_HUNDRED'
         23        ADD_ARRAY_ELEMENT                                ~1      ~12, 900
   68    24        FETCH_CLASS_CONSTANT                             ~13     'ONE_THOUSAND'
         25        ADD_ARRAY_ELEMENT                                ~1      ~13, 1000
         26      > RETURN                                                   ~1
   70    27*     > RETURN                                                   null

End of function getintegertonumeralmap

End of class JoshDiFabio\RomanNumeral.

Class JoshDiFabio\RomanNumeralGenerator:
Function generate:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 6, Position 2 = 10
Branch analysis from position: 6
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 10
2 jumps found. (Code = 47) Position 1 = 12, Position 2 = 14
Branch analysis from position: 12
2 jumps found. (Code = 43) Position 1 = 15, Position 2 = 19
Branch analysis from position: 15
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 19
1 jumps found. (Code = 42) Position 1 = 37
Branch analysis from position: 37
2 jumps found. (Code = 44) Position 1 = 39, Position 2 = 27
Branch analysis from position: 39
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 27
2 jumps found. (Code = 77) Position 1 = 28, Position 2 = 36
Branch analysis from position: 28
2 jumps found. (Code = 78) Position 1 = 29, Position 2 = 36
Branch analysis from position: 29
2 jumps found. (Code = 43) Position 1 = 32, Position 2 = 35
Branch analysis from position: 32
1 jumps found. (Code = 42) Position 1 = 36
Branch analysis from position: 36
2 jumps found. (Code = 44) Position 1 = 39, Position 2 = 27
Branch analysis from position: 39
Branch analysis from position: 27
Branch analysis from position: 35
1 jumps found. (Code = 42) Position 1 = 28
Branch analysis from position: 28
Branch analysis from position: 36
Branch analysis from position: 36
Branch analysis from position: 14
filename:       /in/OntJH
function name:  generate
number of ops:  41
compiled vars:  !0 = $inputNumber, !1 = $numeralString, !2 = $integerToNumeralMap, !3 = $_numeral, !4 = $_numeralAsInteger
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   84     0  E >   RECV                                             !0      
   86     1        INIT_NS_FCALL_BY_NAME                                    'JoshDiFabio%5Cis_integer'
          2        SEND_VAR_EX                                              !0
          3        DO_FCALL                                      0  $5      
          4        BOOL_NOT                                         ~6      $5
          5      > JMPZ                                                     ~6, ->10
   87     6    >   NEW                                              $7      'InvalidArgumentException'
          7        SEND_VAL_EX                                              'Provided+argument+is+not+an+integer.'
          8        DO_FCALL                                      0          
          9      > THROW                                         0          $7
   89    10    >   IS_SMALLER                                       ~9      !0, 1
         11      > JMPNZ_EX                                         ~9      ~9, ->14
         12    >   IS_SMALLER                                       ~10     3999, !0
         13        BOOL                                             ~9      ~10
         14    > > JMPZ                                                     ~9, ->19
   90    15    >   NEW                                              $11     'InvalidArgumentException'
   91    16        SEND_VAL_EX                                              'The+provided+number+is+not+within+the+allowed+range+of+1+to+3999.'
         17        DO_FCALL                                      0          
         18      > THROW                                         0          $11
   94    19    >   ASSIGN                                                   !1, ''
   97    20        INIT_STATIC_METHOD_CALL                                  'JoshDiFabio%5CRomanNumeral', 'getIntegerToNumeralMap'
         21        DO_FCALL                                      0  $14     
         22        ASSIGN                                                   !2, $14
   98    23        INIT_NS_FCALL_BY_NAME                                    'JoshDiFabio%5Ckrsort'
         24        SEND_VAR_EX                                              !2
         25        DO_FCALL                                      0          
  100    26      > JMP                                                      ->37
  101    27    > > FE_RESET_R                                       $17     !2, ->36
         28    > > FE_FETCH_R                                       ~18     $17, !3, ->36
         29    >   ASSIGN                                                   !4, ~18
  107    30        IS_SMALLER_OR_EQUAL                                      !4, !0
         31      > JMPZ                                                     ~20, ->35
  112    32    >   ASSIGN_OP                                     8          !1, !3
  113    33        ASSIGN_OP                                     2          !0, !4
  114    34      > JMP                                                      ->36
  101    35    > > JMP                                                      ->28
         36    >   FE_FREE                                                  $17
  100    37    >   IS_SMALLER                                               0, !0
         38      > JMPNZ                                                    ~23, ->27
  119    39    > > RETURN                                                   !1
  120    40*     > RETURN                                                   null

End of function generate

End of class JoshDiFabio\RomanNumeralGenerator.

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
178.68 ms | 1407 KiB | 16 Q