@ 2023-07-08T14:04:55Z <?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;
}
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Output for 8.1.0 ноль (0) рублей
один (1) рубль
одна тысяча два (1002) рубля
одна тысяча (1000) рублей
две тысячи два (2002) рубля
семь миллионов (7000000) рублей
одиннадцать миллионов двенадцать тысяч тринадцать (11012013) рублей
семь миллионов восемь (7000008) рублей
девятьсот девяносто девять миллионов девятьсот девяносто девять тысяч девятьсот девяносто девять (999999999) рублей
два триллиона десять миллионов одна тысяча (2000010001000) рублей
два триллиона одна тысяча один (2000000001001) рубль
На вашем счету восемьсот семьдесят семь миллиардов девятьсот тридцать три миллиона четыреста две тысячи четыреста двадцать восемь (877933402428) рублей
На вашем счету восемьсот семьдесят один миллиард девятьсот двадцать девять миллионов семьсот сорок четыре тысячи пятьсот тридцать пять (871929744535) рублей
На вашем счету девятьсот пятьдесят два миллиарда сто десять миллионов четыреста восемьдесят семь тысяч четыреста семь (952110487407) рублей
preferences:dark mode live preview ace vim emacs key bindings
50.83 ms | 410 KiB | 5 Q