fork download
  1. <?php
  2.  
  3.  
  4. abstract class Gender
  5. {
  6. const FEMININE = 0;
  7. const MASCULINE = 1;
  8. }
  9.  
  10. class Lexeme
  11. {
  12. public function __construct(string $form1, string $form2, string $form5, int $gender = Gender::MASCULINE)
  13. {
  14. $this->form1 = $form1;
  15. $this->form2 = $form2;
  16. $this->form5 = $form5;
  17. $this->gender = $gender;
  18. }
  19.  
  20. public function getGender(): int
  21. {
  22. return $this->gender;
  23. }
  24.  
  25. public function getFormOf(int $number): string
  26. {
  27. $digit0 = $number % 10;
  28. $digit1 = $number / 10 % 10;
  29.  
  30. if ($digit1 == 1) {
  31. return $this->form5;
  32. } elseif ($digit0 == 1) {
  33. return $this->form1;
  34. } elseif ($digit0 > 1 && $digit0 <= 4) {
  35. return $this->form2;
  36. } else {
  37. return $this->form5;
  38. }
  39. }
  40.  
  41. public static function getEmpty(): Lexeme
  42. {
  43. return new Lexeme("", "", "");
  44. }
  45.  
  46. private int $gender;
  47. private string $form1;
  48. private string $form2;
  49. private string $form5;
  50. }
  51.  
  52. class InWordsBuilder
  53. {
  54. public function __construct(Lexeme $quantity)
  55. {
  56. self::$thousand = new Lexeme("тысяча", "тысячи", "тысяч", Gender::FEMININE);
  57. self::$million = new Lexeme("миллион", "миллиона", "миллионов", Gender::MASCULINE);
  58. self::$billion = new Lexeme("миллиард", "миллиарда", "миллиардов", Gender::MASCULINE);
  59. $this->quantity = $quantity;
  60. }
  61.  
  62. public function build(int $number): string
  63. {
  64. if ($number == 0) {
  65. $quantityStr = $this->quantity->getFormOf(0);
  66. return "ноль" . ($quantityStr == "" ? "" : " $quantityStr");
  67. }
  68. $inParts = new IntegerInParts($number);
  69. $partsOfRecord = [];
  70. if ($number >= 1000000000) {
  71. $partsOfRecord[0] = self::writePartInWords($inParts->getBillions(), self::$billion);
  72. }
  73. if ($number >= 1000000) {
  74. $partsOfRecord[1] = self::writePartInWords($inParts->getMillions(), self::$million);
  75. }
  76. if ($number >= 1000) {
  77. $partsOfRecord[2] = self::writePartInWords($inParts->getThousands(), self::$thousand);
  78. }
  79. $partsOfRecord[3] = self::writePartInWords($inParts->getUnits(), $this->quantity);
  80. return trim(implode(" ", $partsOfRecord));
  81. }
  82.  
  83. private static function writePartInWords(int $number, Lexeme $lexeme): string
  84. {
  85. $digits = [
  86. $number / 100 % 10,
  87. $number / 10 % 10,
  88. $number % 10
  89. ];
  90. $numberMod100 = $number % 100;
  91.  
  92. $parts = [self::$hundreds[$digits[0]]];
  93. if ($digits[1] <= 1) {
  94. if ($digits[2] < 3) {
  95. $parts[1] = self::$oneToThree[$lexeme->getGender()][$digits[2]];
  96. } else {
  97. $parts[1] = self::$threeToNineteen[$numberMod100];
  98. }
  99. } else {
  100. $parts[1] = self::$tens[$digits[1]];
  101. if ($digits[2] < 3) {
  102. $parts[2] = self::$oneToThree[$lexeme->getGender()][$digits[2]];
  103. } else {
  104. $parts[2] = self::$threeToNineteen[$digits[2]];
  105. }
  106. }
  107. $numeral = trim(implode(" ", $parts));
  108. $lexemeInForm = $lexeme->getFormOf($number);
  109. return $numeral . ($lexemeInForm == "" ? "" : " $lexemeInForm");
  110. }
  111.  
  112. private static array $hundreds = ["", "сто", "двести", "триста", "четыреста", "пятьсот",
  113. "шестьсот", "семьсот", "восемьсот", "девятьсот"];
  114. private static array $tens = [2 => "двадцать", "тридцать", "сорок", "пятьдесят", "шестьдесят", "семьдесят",
  115. "восемьдесят", "девяносто"];
  116. private static array $threeToNineteen = [3 => 'три', 'четыре', 'пять', 'шесть', 'семь', 'восемь', 'девять', 'десять',
  117. 'одиннадцать', 'двенадцать', 'тринадцать', 'четырнадцать', 'пятнадцать', 'шестнадцать', 'семнадцать',
  118. 'восемнадцать', 'девятнадцать'];
  119. private static array $oneToThree = [
  120. Gender::FEMININE => ['', 'одна', 'две'],
  121. Gender::MASCULINE => ['', 'один', 'два'],
  122. ];
  123. private static Lexeme $thousand;
  124. private static Lexeme $million;
  125. private static Lexeme $billion;
  126. private Lexeme $quantity;
  127. }
  128.  
  129. class IntegerInParts
  130. {
  131. public function __construct(int $number)
  132. {
  133. $this->billions = $number / 1000000000 % 1000;
  134. $this->millions = $number / 1000000 % 1000;
  135. $this->thousands = $number / 1000 % 1000;
  136. $this->units = $number % 1000;
  137. }
  138.  
  139. public function getBillions(): int
  140. {
  141. return $this->billions;
  142. }
  143.  
  144. public function getMillions(): int
  145. {
  146. return $this->millions;
  147. }
  148.  
  149. public function getThousands(): int
  150. {
  151. return $this->thousands;
  152. }
  153.  
  154. public function getUnits(): int
  155. {
  156. return $this->units;
  157. }
  158.  
  159. private int $billions;
  160. private int $millions;
  161. private int $thousands;
  162. private int $units;
  163. }
  164.  
  165. $builder = new InWordsBuilder(new Lexeme("штука", "штуки", "штук", Gender::FEMININE));
  166. $numbers = [0, 4, 5, 9,
  167. 49, 55, 66, 28, 97, 18, 85, 96,
  168. 673, 242, 463, 592, 664, 259, 170, 382,
  169. 6428, 5454, 2175, 6234, 7091, 5236, 4533, 1244,
  170. 99189, 70540, 64063, 78756, 35080, 15626, 36327, 84276,
  171. 528070, 760165, 873158, 566844, 843370, 415865, 997742, 890570,
  172. 6855775, 4913491, 6181936, 7298680, 7625891, 7733251, 1001001, 9147526,
  173. 75269465, 98207441, 46370258, 26467052, 67385218, 74961612, 97937978, 63423923,
  174. 313248348, 604730178, 342676693, 965300262, 175878814, 796606802, 233396657, 213578532,
  175. 5281552249, 2361786413, 9463336049, 6982021856, 8707095076, 7869601075, 4398378123, 2223366077];
  176. foreach ($numbers as $number) {
  177. printf("%-12d= %s\n", $number, $builder->build($number));
  178. }
  179.  
Runtime error #stdin #stdout #stderr 0.02s 25796KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
PHP Parse error:  syntax error, unexpected 'int' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST) in /home/IiOZvH/prog.php on line 48