3v4l.org

run code in 300+ PHP versions simultaneously
<?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; }
Output for 8.1.0
ноль (0) рублей один (1) рубль одна тысяча два (1002) рубля одна тысяча (1000) рублей две тысячи два (2002) рубля семь миллионов (7000000) рублей одиннадцать миллионов двенадцать тысяч тринадцать (11012013) рублей семь миллионов восемь (7000008) рублей девятьсот девяносто девять миллионов девятьсот девяносто девять тысяч девятьсот девяносто девять (999999999) рублей два триллиона десять миллионов одна тысяча (2000010001000) рублей два триллиона одна тысяча один (2000000001001) рубль На вашем счету восемьсот семьдесят семь миллиардов девятьсот тридцать три миллиона четыреста две тысячи четыреста двадцать восемь (877933402428) рублей На вашем счету восемьсот семьдесят один миллиард девятьсот двадцать девять миллионов семьсот сорок четыре тысячи пятьсот тридцать пять (871929744535) рублей На вашем счету девятьсот пятьдесят два миллиарда сто десять миллионов четыреста восемьдесят семь тысяч четыреста семь (952110487407) рублей

preferences:
50.83 ms | 410 KiB | 5 Q