3v4l.org

run code in 300+ PHP versions simultaneously
<?php declare(strict_types=1); /** * @return int[] */ function splitInto3DigitNums(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 convert3DigitNumsToText(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 = splitInto3DigitNums($number); $threeDigitNums = removeZeroValues($threeDigitNums); $threeDigitTextNums = convert3DigitNumsToText($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:
20.54 ms | 410 KiB | 5 Q