<?php
declare(strict_types=1);
/**
* @return int[]
*/
function splitIntoThreeDigitNums(int $number): array
{
$threeDigitNumbers = [];
while ($number > 0) {
$threeDigitNumbers[] = $number % 1000;
$number = (int) floor($number / 1000);
}
return array_reverse($threeDigitNumbers, true);
}
function isFemaleNumber(int $powerOf1000, int $number): bool
{
return ($powerOf1000 === 1 && $number === 1) || ($powerOf1000 === 1 && $number === 2);
}
function spellSmallNumber(int $number, int $powerOf1000): string
{
$smallNumWords = [];
$lastTwoDigit = $number % 100;
$ones = $number % 10;
$tens = $lastTwoDigit - $ones;
$hundreds = $number - $tens - $ones;
$spelling = [
0 => 'ноль', 1 => 'один', 2 => 'два', 3 => 'три', 4 => 'четыре',
5 => 'пять', 6 => 'шесть', 7 => 'семь', 8 => 'восемь', 9 => 'девять',
10 => 'десять', 11 => 'одиннадцать', 12 => 'двенадцать', 13 => 'тринадцать',
14 => 'четырнадцать', 15 => 'пятнадцать', 16 => 'шестнадцать',
17 => 'семнадцать', 18 => 'восемнадцать', 19 => 'девятнадцать',
20 => 'двадцать', 30 => 'тридцать', 40 => 'сорок', 50 => 'пятьдесят',
60 => 'шестьдесят', 70 => 'семьдесят', 80 => 'восемьдесят', 90 => 'девяносто',
100 => 'сто', 200 => 'двести', 300 => 'триста', 400 => 'четыреста',
500 => 'пятьсот', 600 => 'шестьсот', 700 => 'семьсот', 800 => 'восемьсот',
900 => 'девятьсот'
];
$femSpelling = [1 => 'одна', 2 => 'две'];
if ($number === 0) {
return $spelling[$number];
}
if ($hundreds !== 0) {
$smallNumWords[] = $spelling[$hundreds];
}
if ($lastTwoDigit >= 10 && $lastTwoDigit <= 19) {
$smallNumWords[] = $spelling[$lastTwoDigit];
} else {
if ($tens !== 0) {
$smallNumWords[] = $spelling[$tens];
}
if ($ones !== 0) {
$smallNumWords[] = (isFemaleNumber($powerOf1000, $ones)) ? $femSpelling[$ones] : $spelling[$ones];
}
}
return implode(' ', $smallNumWords);
}
function getWordForm(int $number, string $wordForm1, string $wordForm2, string $wordForm3): string
{
$lastTwoDigits = $number % 100;
$lastDigit = $number % 10;
if (
in_array($lastTwoDigits, [11, 12, 13, 14, 15, 16, 17, 18, 19])
|| in_array($lastDigit, [0, 5, 6, 7, 8, 9])
) {
return $wordForm3;
}
if (
$lastDigit === 1
) {
return $wordForm1;
}
return $wordForm2;
}
/**
* @param int[] $threeDigitNums
* @return string[]
*/
function getInclinedNamesOfPowerOf1000(array $threeDigitNums): array
{
$inclinedNames = [];
$wordForms = [
'' => ['', '', ''],
'тысяча' => ['тысяча', 'тысячи', 'тысяч'],
'миллион' => ['миллион', 'миллиона', 'миллионов'],
'миллиард' => ['миллиард', 'миллиарда', 'миллиардов'],
'триллион' => ['триллион', 'триллиона', 'триллионов']
];
foreach ($threeDigitNums as $powerOf1000 => $threeDigitNum) {
$word = array_keys($wordForms)[$powerOf1000];
$inclinedNames[$powerOf1000] = getWordForm($threeDigitNum, ...$wordForms[$word]);
}
return $inclinedNames;
}
/**
* @param int[] $nums
* @return int[]
*/
function removeZeroValues(array $nums): array
{
$withOutZeros = [];
foreach ($nums as $key => $num) {
if ($num !== 0) {
$withOutZeros[$key] = $num;
}
}
return $withOutZeros;
}
/**
* @param int[] $threeDigitNums
* @return string[]
*/
function convertThreeDigitNumsToText(array $threeDigitNums): array
{
$textNums = [];
foreach ($threeDigitNums as $powerOf1000 => $threeDigitNum) {
$textNums[$powerOf1000] = spellSmallNumber($threeDigitNum, $powerOf1000);
}
return $textNums;
}
/**
* @param string[] $numWords
* @param string[] $postfixes
* @return string[]
*/
function concatenateValuesFromArrays(array $numWords, array $postfixes): array
{
$concatenatedValues = [];
foreach ($numWords as $key => $numWord) {
$concatenatedValues[$key] = $numWord . ' ' . $postfixes[$key];
$concatenatedValues[$key] = trim($concatenatedValues[$key]);
}
return $concatenatedValues;
}
function convertNumberToWords(int $number): string
{
if ($number === 0) {
return 'ноль (0) рублей';
}
if ($number < 0 || $number > 999_999_999_999_999) {
throw new RuntimeException('Error: Your number is out of range');
}
$threeDigitNums = splitIntoThreeDigitNums($number);
$threeDigitNums = removeZeroValues($threeDigitNums);
$threeDigitTextNums = convertThreeDigitNumsToText($threeDigitNums);
$inclinedNamesOfPowerOf1000 = getInclinedNamesOfPowerOf1000($threeDigitNums);
$arrOfNumerals = concatenateValuesFromArrays($threeDigitTextNums, $inclinedNamesOfPowerOf1000);
$roubleForm = getWordForm($number, 'рубль', 'рубля', 'рублей');
$result = implode(' ', $arrOfNumerals) . " ($number) ";
$result .= $roubleForm;
return $result;
}
//Проверь свою программу на таких числах: 999999999, 0, 1, 11012013, 7000008, 1002, 1000, 7000000.
$testNums = [0, 1, 1002, 1000, 2002, 7000000, 11012013, 7000008, 999999999, 2_000_010_001_000, 2_000_000_001_001];
foreach ($testNums as $testNum) {
echo convertNumberToWords($testNum) . PHP_EOL;
}
for ($i = 1; $i <= 3; $i++) {
$amount = random_int(1, 999_999_999_999);
$text = convertNumberToWords($amount);
echo "На вашем счету $text" . PHP_EOL;
}
preferences:
23.13 ms | 410 KiB | 5 Q