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

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