@ 2023-07-08T10:44:50Z <?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;
}
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) рубль
На вашем счету триста тридцать три миллиарда шестьсот пятьдесят четыре миллиона пятьсот пятьдесят четыре тысячи пятьсот шестьдесят четыре (333654554564) рубля
На вашем счету шестьсот девяносто пять миллиардов девятьсот четырнадцать миллионов четыреста сорок девять тысяч девятьсот семьдесят три (695914449973) рубля
На вашем счету пятьсот семь миллиардов триста девяносто четыре миллиона шестьсот одна тысяча пятьсот шестьдесят три (507394601563) рубля
preferences:dark mode live preview ace vim emacs key bindings
55.8 ms | 410 KiB | 5 Q