fork(7) download
  1. /*Во многих серьезных документах принято писать денежные суммы цифрами и прописью, вот так: «триста двадцать шесть (326)
  2. рублей», «две тысячи один (2001) рубль». Давай избавим людей от рутинной работы, и поручим склонение слов роботам и
  3. языку PHP.
  4.  
  5. Дана сумма, находящаяся в банке на счету, в рублях. Вывести ее в текстовом виде вроде "шестнадцать миллионов десять
  6. тысяч три (16010003) рубля".
  7. */
  8. <?php
  9. //mb_internal_encoding("utf-8");
  10. function getDigits(int $number, int $i){//Возвращает первые цифры для переданного числа
  11. return intval(floor($number / pow(10, $i)));
  12. }
  13. function getRemainder(int $number, int $i){//Возвращает остаток числа
  14. return intval(floor($number % pow(10, $i)));
  15. }
  16. function word(int $number = 0, array $words) //Возвращает "рубль", "рубля" или "рублей"
  17. {
  18. if ($number % 10 == 1 && $number != 11) {
  19. return $words[0];
  20. } elseif ($number % 10 >= 2 && $number % 10 < 5 && ($number % 100 > 15 || $number % 100 < 5)) {
  21. return $words[1];
  22. } else {
  23. return $words[2];
  24. }
  25. }
  26.  
  27. function digitsToWords(int $number, array $numbers, bool $isFemale){//Проверяет сотни, десятки и единицы и возвращает их, если они != 0
  28. $femNumbers = [1 => "одна", "две"];
  29. $resultExp = [];
  30. $hundred = intval(floor($number / 100) * 100);
  31. $tensAndUnits = $number % 100;
  32. $units = $tensAndUnits % 10;
  33. if ($hundred >= 100) {
  34. $resultExp[] = $numbers[$hundred];
  35. }
  36. if ($tensAndUnits != 0) {
  37. if ($tensAndUnits > 9 && $tensAndUnits <= 20) {//Если число в этом диапазоне, то нет необходимости писать единицы
  38. $resultExp[] = $numbers[$tensAndUnits];
  39. } else{
  40. $tens = intval(floor($tensAndUnits / 10)) * 10;
  41. if($tens != 0){
  42. $resultExp[] = $numbers[$tens];
  43. }
  44. if ($units != 0) {
  45. if($isFemale && ($units == 1 || $units == 2)){//На жр нужно заменять только 1 или 2, и только перед словом тысяча(и)
  46. $resultExp[] = $femNumbers[$units];
  47. } else{
  48. $resultExp[] = $numbers[$units];
  49. }
  50. }
  51. }
  52. }
  53. return implode(" ", $resultExp);
  54. }
  55.  
  56. $numbers = ["ноль", "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять", "десять",
  57. "одиннадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать",
  58. "двадцать", 30 => "тридцать", 40 => "сорок", 50 => "пятьдесят", 60 => "шестьдесят", 70 => "семьдесят", 80 => "восемьдесят", 90 => "девяносто",
  59. 100 => "сто", 200 => "двести", 300 => "триста", 400 => "четыреста", 500 => "пятьсот", 600 => "шесьтсот", 700 => "семьсот", 800 => "восемьсот", 900 => "девятьсот"];
  60.  
  61. //Первый элемент при 1, 2-ой при 2-4, 3 при остальных
  62. $thousands = ["тысяча", "тысячи", "тысяч"];
  63. $millions = ["миллион", "миллиона", "миллионов"];
  64. $billions = ["миллиард", "миллиарда", "миллиардов"];
  65. $rubles = ["рубль", "рубля", "рублей"];
  66. $number = 999001012;
  67. $resultExp = [];//Здесь хранится результат
  68. if($number != 0){
  69. while ($number >= 1) {
  70. $isFemale = false;//Женский род
  71. $i = intval(log10(abs($number))) + 1;//Количество цифр = log10(n) + 1;
  72. $denomination = [];//В зависимости от количества цифр здесь будут хранится тысячи, миллионы или миллиарды
  73. if ($i >= 4) {
  74. if ($i >= 4 && $i < 7) {
  75. $denomination = $thousands;
  76. $isFemale = true;
  77. } elseif ($i >= 7 && $i < 10) {
  78. $denomination = $millions;
  79. } else {
  80. $denomination = $billions;
  81. }
  82. $number = intval($number);
  83. if ($i % 3 == 0) {
  84. $threeDigits = getDigits($number, $i - 3);
  85. $number = getRemainder($number, $i - 3);
  86. $resultExp[] = digitsToWords($threeDigits, $numbers, $isFemale);
  87. $resultExp[] = word($threeDigits, $denomination);
  88. } elseif ($i % 3 == 2) {
  89. $firstTwoDigit = getDigits($number, $i - 2);
  90. $number = getRemainder($number, $i - 2);
  91. $resultExp[] = digitsToWords($firstTwoDigit, $numbers, $isFemale);
  92. $resultExp[] = word($firstTwoDigit, $denomination);
  93. } else {
  94. $firstDigit = getDigits($number, $i - 1);
  95. $number = getRemainder($number, $i - 1);
  96. //echo $number . "\n";
  97. $resultExp[] = digitsToWords($firstDigit, $numbers, $isFemale);
  98. $resultExp[] = word($firstDigit, $denomination);
  99. }
  100. } else {
  101. $resultExp[] = digitsToWords($number, $numbers, false);
  102. $resultExp[] = word($number, $rubles);
  103. break;//Выходим из цикла, т.к. уже расписали все цифры
  104. }
  105. }
  106. } else{
  107. $resultExp[] = $numbers[$number];
  108. $resultExp[] = word($number, $rubles);
  109. }
  110. echo "Result: " . implode(" ", $resultExp) . "\n";
  111. ?>
Success #stdin #stdout 0.01s 82560KB
stdin
Standard input is empty
stdout
/*Во многих серьезных документах принято писать денежные суммы цифрами и прописью, вот так: «триста двадцать шесть (326)
рублей», «две тысячи один (2001) рубль». Давай избавим людей от рутинной работы, и поручим склонение слов роботам и
языку PHP.

Дана сумма, находящаяся в банке на счету, в рублях. Вывести ее в текстовом виде вроде "шестнадцать миллионов десять
тысяч три (16010003) рубля".
*/
Result: девятьсот девяносто девять миллионов одна тысяча двенадцать рублей