/*Во многих серьезных документах принято писать денежные суммы цифрами и прописью, вот так: «триста двадцать шесть (326)
рублей», «две тысячи один (2001) рубль». Давай избавим людей от рутинной работы, и поручим склонение слов роботам и
языку PHP.
Дана сумма, находящаяся в банке на счету, в рублях. Вывести ее в текстовом виде вроде "шестнадцать миллионов десять
тысяч три (16010003) рубля".
*/
<?php
//mb_internal_encoding("utf-8");
function amountOfDigits( int $number ) : int
{
return intval ( log10 ( abs ( $number ) ) ) + 1 ; //Количество цифр = log10(n) + 1; }
function getFirstDigits( int $number , int $i ) : int
{ //Возвращает первые цифры для переданного числа
}
function getRemainder( int $number , int $i ) : int
{ //Возвращает остаток числа
}
function word
( int
$number , array $words ) : string
//Возвращает "рубль", "рубля" или "рублей" {
if ( $number % 10 == 1 && $number != 11 ) {
return $words [ 0 ] ;
} elseif ( $number % 10 >= 2 && $number % 10 < 5 && ( $number % 100 > 15 || $number % 100 < 5 ) ) {
return $words [ 1 ] ;
} else {
return $words [ 2 ] ;
}
}
function digitsToWords( int $number , bool $isFemale ) : string
{ //Проверяет сотни, десятки и единицы и возвращает их, если они != 0
$numbers = [ "ноль" , "один" , "два" , "три" , "четыре" , "пять" , "шесть" , "семь" , "восемь" , "девять" , "десять" ,
"одиннадцать" , "двенадцать" , "тринадцать" , "четырнадцать" , "пятнадцать" , "шестнадцать" , "семнадцать" , "восемнадцать" , "девятнадцать" ,
"двадцать" , 30 => "тридцать" , 40 => "сорок" , 50 => "пятьдесят" , 60 => "шестьдесят" , 70 => "семьдесят" , 80 => "восемьдесят" , 90 => "девяносто" ,
100 => "сто" , 200 => "двести" , 300 => "триста" , 400 => "четыреста" , 500 => "пятьсот" , 600 => "шесьтсот" , 700 => "семьсот" , 800 => "восемьсот" , 900 => "девятьсот" ] ;
if ( $number == 0 ) {
return $numbers [ $number ] ;
}
$femNumbers = [ 1 => "одна" , "две" ] ;
$resultExp = [ ] ;
$hundred = intval ( floor ( $number / 100 ) * 100 ) ; //Определяем количество сотен $tensAndUnits = $number % 100 ;
$units = $tensAndUnits % 10 ;
if ( $hundred >= 100 ) {
$resultExp [ ] = $numbers [ $hundred ] ;
}
if ( $tensAndUnits != 0 ) {
if ( $tensAndUnits > 9 && $tensAndUnits <= 20 ) { //Если число в этом диапазоне, то нет необходимости писать единицы
$resultExp [ ] = $numbers [ $tensAndUnits ] ;
} else {
if ( $tens != 0 ) {
$resultExp [ ] = $numbers [ $tens ] ;
}
if ( $units != 0 ) {
if ( $isFemale && ( $units == 1 || $units == 2 ) ) { //На жр нужно заменять только 1 или 2, и только перед словом тысяча(и)
$resultExp [ ] = $femNumbers [ $units ] ;
} else {
$resultExp [ ] = $numbers [ $units ] ;
}
}
}
}
}
//Первый элемент при 1, 2-ой при 2-4, 3 при остальных
$thousands = [ "тысяча" , "тысячи" , "тысяч" ] ;
$millions = [ "миллион" , "миллиона" , "миллионов" ] ;
$billions = [ "миллиард" , "миллиарда" , "миллиардов" ] ;
$rubles = [ "рубль" , "рубля" , "рублей" ] ;
$number = 987123 ; // миллиардах вместо 909123000 возвращается 614155704
$resultExp = [ ] ; //Здесь хранится результат
//echo PHP_INT_MAX . "\n";
if ( $number == 0 ) {
$resultExp [ ] = digitsToWords( $number , false ) ;
$resultExp [ ] = word( $number , $rubles ) ;
}
while ( $number >= 1 ) {
$isFemale = false ; //Женский род
$amountOfDigits = amountOfDigits( $number ) ;
$denomination = [ ] ; //В зависимости от количества цифр здесь будут хранится тысячи, миллионы или миллиарды
if ( $amountOfDigits >= 4 ) {
if ( $amountOfDigits >= 4 && $amountOfDigits < 7 ) {
$denomination = $thousands ;
$isFemale = true ;
} elseif ( $amountOfDigits >= 7 && $amountOfDigits < 10 ) {
$denomination = $millions ;
} else {
$denomination = $billions ;
}
while ( 1 ) {
$firstDigits = getFirstDigits( $number , ( $amountOfDigits % 3 != 0 ) ? $amountOfDigits - $amountOfDigits % 3 : $amountOfDigits - 3 ) ;
$number = getRemainder( $number , ( $amountOfDigits % 3 != 0 ) ? $amountOfDigits - $amountOfDigits % 3 : $amountOfDigits - 3 ) ;
$resultExp [ ] = digitsToWords( $firstDigits , $isFemale ) ;
$resultExp [ ] = word( $firstDigits , $denomination ) ;
break ;
}
} else {
$resultExp [ ] = digitsToWords( $number , $isFemale ) ;
$resultExp [ ] = word( $number , $rubles ) ;
break ; //Выходим из цикла, т.к. уже расписали все цифры
}
}
echo "Result: " . implode ( " " , $resultExp ) . "\n " ; ?>
LyrQktC+INC80L3QvtCz0LjRhSDRgdC10YDRjNC10LfQvdGL0YUg0LTQvtC60YPQvNC10L3RgtCw0YUg0L/RgNC40L3Rj9GC0L4g0L/QuNGB0LDRgtGMINC00LXQvdC10LbQvdGL0LUg0YHRg9C80LzRiyDRhtC40YTRgNCw0LzQuCDQuCDQv9GA0L7Qv9C40YHRjNGOLCDQstC+0YIg0YLQsNC6OiDCq9GC0YDQuNGB0YLQsCDQtNCy0LDQtNGG0LDRgtGMINGI0LXRgdGC0YwgKDMyNikK0YDRg9Cx0LvQtdC5wrssIMKr0LTQstC1INGC0YvRgdGP0YfQuCDQvtC00LjQvSAoMjAwMSkg0YDRg9Cx0LvRjMK7LiDQlNCw0LLQsNC5INC40LfQsdCw0LLQuNC8INC70Y7QtNC10Lkg0L7RgiDRgNGD0YLQuNC90L3QvtC5INGA0LDQsdC+0YLRiywg0Lgg0L/QvtGA0YPRh9C40Lwg0YHQutC70L7QvdC10L3QuNC1INGB0LvQvtCyINGA0L7QsdC+0YLQsNC8INC4CtGP0LfRi9C60YMgUEhQLgoK0JTQsNC90LAg0YHRg9C80LzQsCwg0L3QsNGF0L7QtNGP0YnQsNGP0YHRjyDQsiDQsdCw0L3QutC1INC90LAg0YHRh9C10YLRgywg0LIg0YDRg9Cx0LvRj9GFLiDQktGL0LLQtdGB0YLQuCDQtdC1INCyINGC0LXQutGB0YLQvtCy0L7QvCDQstC40LTQtSDQstGA0L7QtNC1ICLRiNC10YHRgtC90LDQtNGG0LDRgtGMINC80LjQu9C70LjQvtC90L7QsiDQtNC10YHRj9GC0YwK0YLRi9GB0Y/RhyDRgtGA0LggKDE2MDEwMDAzKSDRgNGD0LHQu9GPIi4KKi8KPD9waHAKLy9tYl9pbnRlcm5hbF9lbmNvZGluZygidXRmLTgiKTsKZXJyb3JfcmVwb3J0aW5nKC0xKTsKZnVuY3Rpb24gYW1vdW50T2ZEaWdpdHMoaW50ICRudW1iZXIpOiBpbnQKewogICAgcmV0dXJuIGludHZhbChsb2cxMChhYnMoJG51bWJlcikpKSArIDE7Ly/QmtC+0LvQuNGH0LXRgdGC0LLQviDRhtC40YTRgCA9IGxvZzEwKG4pICsgMTsKfQoKZnVuY3Rpb24gZ2V0Rmlyc3REaWdpdHMoaW50ICRudW1iZXIsIGludCAkaSk6IGludAp7Ly/QktC+0LfQstGA0LDRidCw0LXRgiDQv9C10YDQstGL0LUg0YbQuNGE0YDRiyDQtNC70Y8g0L/QtdGA0LXQtNCw0L3QvdC+0LPQviDRh9C40YHQu9CwCiAgICByZXR1cm4gaW50dmFsKGZsb29yKCRudW1iZXIgLyBwb3coMTAsICRpKSkpOwp9CgpmdW5jdGlvbiBnZXRSZW1haW5kZXIoaW50ICRudW1iZXIsIGludCAkaSk6IGludAp7Ly/QktC+0LfQstGA0LDRidCw0LXRgiDQvtGB0YLQsNGC0L7QuiDRh9C40YHQu9CwCiAgICByZXR1cm4gaW50dmFsKGZsb29yKCRudW1iZXIgJSBwb3coMTAsICRpKSkpOwp9CgpmdW5jdGlvbiB3b3JkKGludCAkbnVtYmVyLCBhcnJheSAkd29yZHMpOiBzdHJpbmcgLy/QktC+0LfQstGA0LDRidCw0LXRgiAi0YDRg9Cx0LvRjCIsICLRgNGD0LHQu9GPIiDQuNC70LggItGA0YPQsdC70LXQuSIKewogICAgaWYgKCRudW1iZXIgJSAxMCA9PSAxICYmICRudW1iZXIgIT0gMTEpIHsKICAgICAgICByZXR1cm4gJHdvcmRzWzBdOwogICAgfSBlbHNlaWYgKCRudW1iZXIgJSAxMCA+PSAyICYmICRudW1iZXIgJSAxMCA8IDUgJiYgKCRudW1iZXIgJSAxMDAgPiAxNSB8fCAkbnVtYmVyICUgMTAwIDwgNSkpIHsKICAgICAgICByZXR1cm4gJHdvcmRzWzFdOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gJHdvcmRzWzJdOwogICAgfQp9CgpmdW5jdGlvbiBkaWdpdHNUb1dvcmRzKGludCAkbnVtYmVyLCBib29sICRpc0ZlbWFsZSk6IHN0cmluZwp7Ly/Qn9GA0L7QstC10YDRj9C10YIg0YHQvtGC0L3QuCwg0LTQtdGB0Y/RgtC60Lgg0Lgg0LXQtNC40L3QuNGG0Ysg0Lgg0LLQvtC30LLRgNCw0YnQsNC10YIg0LjRhSwg0LXRgdC70Lgg0L7QvdC4ICE9IDAKICAgICRudW1iZXJzID0gWyLQvdC+0LvRjCIsICLQvtC00LjQvSIsICLQtNCy0LAiLCAi0YLRgNC4IiwgItGH0LXRgtGL0YDQtSIsICLQv9GP0YLRjCIsICLRiNC10YHRgtGMIiwgItGB0LXQvNGMIiwgItCy0L7RgdC10LzRjCIsICLQtNC10LLRj9GC0YwiLCAi0LTQtdGB0Y/RgtGMIiwKICAgICAgICAi0L7QtNC40L3QvdCw0LTRhtCw0YLRjCIsICLQtNCy0LXQvdCw0LTRhtCw0YLRjCIsICLRgtGA0LjQvdCw0LTRhtCw0YLRjCIsICLRh9C10YLRi9GA0L3QsNC00YbQsNGC0YwiLCAi0L/Rj9GC0L3QsNC00YbQsNGC0YwiLCAi0YjQtdGB0YLQvdCw0LTRhtCw0YLRjCIsICLRgdC10LzQvdCw0LTRhtCw0YLRjCIsICLQstC+0YHQtdC80L3QsNC00YbQsNGC0YwiLCAi0LTQtdCy0Y/RgtC90LDQtNGG0LDRgtGMIiwKICAgICAgICAi0LTQstCw0LTRhtCw0YLRjCIsIDMwID0+ICLRgtGA0LjQtNGG0LDRgtGMIiwgNDAgPT4gItGB0L7RgNC+0LoiLCA1MCA9PiAi0L/Rj9GC0YzQtNC10YHRj9GCIiwgNjAgPT4gItGI0LXRgdGC0YzQtNC10YHRj9GCIiwgNzAgPT4gItGB0LXQvNGM0LTQtdGB0Y/RgiIsIDgwID0+ICLQstC+0YHQtdC80YzQtNC10YHRj9GCIiwgOTAgPT4gItC00LXQstGP0L3QvtGB0YLQviIsCiAgICAgICAgMTAwID0+ICLRgdGC0L4iLCAyMDAgPT4gItC00LLQtdGB0YLQuCIsIDMwMCA9PiAi0YLRgNC40YHRgtCwIiwgNDAwID0+ICLRh9C10YLRi9GA0LXRgdGC0LAiLCA1MDAgPT4gItC/0Y/RgtGM0YHQvtGCIiwgNjAwID0+ICLRiNC10YHRjNGC0YHQvtGCIiwgNzAwID0+ICLRgdC10LzRjNGB0L7RgiIsIDgwMCA9PiAi0LLQvtGB0LXQvNGM0YHQvtGCIiwgOTAwID0+ICLQtNC10LLRj9GC0YzRgdC+0YIiXTsKICAgIGlmICgkbnVtYmVyID09IDApIHsKICAgICAgICByZXR1cm4gJG51bWJlcnNbJG51bWJlcl07CiAgICB9CiAgICAkZmVtTnVtYmVycyA9IFsxID0+ICLQvtC00L3QsCIsICLQtNCy0LUiXTsKICAgICRyZXN1bHRFeHAgPSBbXTsKICAgICRodW5kcmVkID0gaW50dmFsKGZsb29yKCRudW1iZXIgLyAxMDApICogMTAwKTsvL9Ce0L/RgNC10LTQtdC70Y/QtdC8INC60L7Qu9C40YfQtdGB0YLQstC+INGB0L7RgtC10L0KICAgICR0ZW5zQW5kVW5pdHMgPSAkbnVtYmVyICUgMTAwOwogICAgJHVuaXRzID0gJHRlbnNBbmRVbml0cyAlIDEwOwoKICAgIGlmICgkaHVuZHJlZCA+PSAxMDApIHsKICAgICAgICAkcmVzdWx0RXhwW10gPSAkbnVtYmVyc1skaHVuZHJlZF07CiAgICB9CiAgICBpZiAoJHRlbnNBbmRVbml0cyAhPSAwKSB7CiAgICAgICAgaWYgKCR0ZW5zQW5kVW5pdHMgPiA5ICYmICR0ZW5zQW5kVW5pdHMgPD0gMjApIHsvL9CV0YHQu9C4INGH0LjRgdC70L4g0LIg0Y3RgtC+0Lwg0LTQuNCw0L/QsNC30L7QvdC1LCDRgtC+INC90LXRgiDQvdC10L7QsdGF0L7QtNC40LzQvtGB0YLQuCDQv9C40YHQsNGC0Ywg0LXQtNC40L3QuNGG0YsKICAgICAgICAgICAgJHJlc3VsdEV4cFtdID0gJG51bWJlcnNbJHRlbnNBbmRVbml0c107CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRlbnMgPSBpbnR2YWwoZmxvb3IoJHRlbnNBbmRVbml0cyAvIDEwKSkgKiAxMDsKICAgICAgICAgICAgaWYgKCR0ZW5zICE9IDApIHsKICAgICAgICAgICAgICAgICRyZXN1bHRFeHBbXSA9ICRudW1iZXJzWyR0ZW5zXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJHVuaXRzICE9IDApIHsKICAgICAgICAgICAgICAgIGlmICgkaXNGZW1hbGUgJiYgKCR1bml0cyA9PSAxIHx8ICR1bml0cyA9PSAyKSkgey8v0J3QsCDQttGAINC90YPQttC90L4g0LfQsNC80LXQvdGP0YLRjCDRgtC+0LvRjNC60L4gMSDQuNC70LggMiwg0Lgg0YLQvtC70YzQutC+INC/0LXRgNC10LQg0YHQu9C+0LLQvtC8INGC0YvRgdGP0YfQsCjQuCkKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0RXhwW10gPSAkZmVtTnVtYmVyc1skdW5pdHNdOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0RXhwW10gPSAkbnVtYmVyc1skdW5pdHNdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGltcGxvZGUoIiAiLCAkcmVzdWx0RXhwKTsKfQoKLy/Qn9C10YDQstGL0Lkg0Y3Qu9C10LzQtdC90YIg0L/RgNC4IDEsIDIt0L7QuSDQv9GA0LggMi00LCAzINC/0YDQuCDQvtGB0YLQsNC70YzQvdGL0YUKJHRob3VzYW5kcyA9IFsi0YLRi9GB0Y/Rh9CwIiwgItGC0YvRgdGP0YfQuCIsICLRgtGL0YHRj9GHIl07CiRtaWxsaW9ucyA9IFsi0LzQuNC70LvQuNC+0L0iLCAi0LzQuNC70LvQuNC+0L3QsCIsICLQvNC40LvQu9C40L7QvdC+0LIiXTsKJGJpbGxpb25zID0gWyLQvNC40LvQu9C40LDRgNC0IiwgItC80LjQu9C70LjQsNGA0LTQsCIsICLQvNC40LvQu9C40LDRgNC00L7QsiJdOwokcnVibGVzID0gWyLRgNGD0LHQu9GMIiwgItGA0YPQsdC70Y8iLCAi0YDRg9Cx0LvQtdC5Il07CiRudW1iZXIgPSA5ODcxMjM7Ly8g0LzQuNC70LvQuNCw0YDQtNCw0YUg0LLQvNC10YHRgtC+IDkwOTEyMzAwMCDQstC+0LfQstGA0LDRidCw0LXRgtGB0Y8gNjE0MTU1NzA0CiRyZXN1bHRFeHAgPSBbXTsvL9CX0LTQtdGB0Ywg0YXRgNCw0L3QuNGC0YHRjyDRgNC10LfRg9C70YzRgtCw0YIKLy9lY2hvIFBIUF9JTlRfTUFYIC4gIlxuIjsKaWYgKCRudW1iZXIgPT0gMCkgewogICAgJHJlc3VsdEV4cFtdID0gZGlnaXRzVG9Xb3JkcygkbnVtYmVyLCBmYWxzZSk7CiAgICAkcmVzdWx0RXhwW10gPSB3b3JkKCRudW1iZXIsICRydWJsZXMpOwp9CndoaWxlICgkbnVtYmVyID49IDEpIHsKICAgICRpc0ZlbWFsZSA9IGZhbHNlOy8v0JbQtdC90YHQutC40Lkg0YDQvtC0CiAgICAkYW1vdW50T2ZEaWdpdHMgPSBhbW91bnRPZkRpZ2l0cygkbnVtYmVyKTsKICAgICRkZW5vbWluYXRpb24gPSBbXTsvL9CSINC30LDQstC40YHQuNC80L7RgdGC0Lgg0L7RgiDQutC+0LvQuNGH0LXRgdGC0LLQsCDRhtC40YTRgCDQt9C00LXRgdGMINCx0YPQtNGD0YIg0YXRgNCw0L3QuNGC0YHRjyDRgtGL0YHRj9GH0LgsINC80LjQu9C70LjQvtC90Ysg0LjQu9C4INC80LjQu9C70LjQsNGA0LTRiwogICAgaWYgKCRhbW91bnRPZkRpZ2l0cyA+PSA0KSB7CiAgICAgICAgaWYgKCRhbW91bnRPZkRpZ2l0cyA+PSA0ICYmICRhbW91bnRPZkRpZ2l0cyA8IDcpIHsKICAgICAgICAgICAgJGRlbm9taW5hdGlvbiA9ICR0aG91c2FuZHM7CiAgICAgICAgICAgICRpc0ZlbWFsZSA9IHRydWU7CiAgICAgICAgfSBlbHNlaWYgKCRhbW91bnRPZkRpZ2l0cyA+PSA3ICYmICRhbW91bnRPZkRpZ2l0cyA8IDEwKSB7CiAgICAgICAgICAgICRkZW5vbWluYXRpb24gPSAkbWlsbGlvbnM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGRlbm9taW5hdGlvbiA9ICRiaWxsaW9uczsKICAgICAgICB9CiAgICAgICAgJG51bWJlciA9IGludHZhbCgkbnVtYmVyKTsKICAgICAgICB3aGlsZSAoMSkgewogICAgICAgICAgICAkZmlyc3REaWdpdHMgPSBnZXRGaXJzdERpZ2l0cygkbnVtYmVyLCAoJGFtb3VudE9mRGlnaXRzICUgMyAhPSAwKSA/ICRhbW91bnRPZkRpZ2l0cyAtICRhbW91bnRPZkRpZ2l0cyAlIDMgOiAkYW1vdW50T2ZEaWdpdHMgLSAzKTsKICAgICAgICAgICAgJG51bWJlciA9IGdldFJlbWFpbmRlcigkbnVtYmVyLCAoJGFtb3VudE9mRGlnaXRzICUgMyAhPSAwKSA/ICRhbW91bnRPZkRpZ2l0cyAtICRhbW91bnRPZkRpZ2l0cyAlIDMgOiAkYW1vdW50T2ZEaWdpdHMgLSAzKTsKICAgICAgICAgICAgJHJlc3VsdEV4cFtdID0gZGlnaXRzVG9Xb3JkcygkZmlyc3REaWdpdHMsICRpc0ZlbWFsZSk7CiAgICAgICAgICAgICRyZXN1bHRFeHBbXSA9IHdvcmQoJGZpcnN0RGlnaXRzLCAkZGVub21pbmF0aW9uKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAkcmVzdWx0RXhwW10gPSBkaWdpdHNUb1dvcmRzKCRudW1iZXIsICRpc0ZlbWFsZSk7CiAgICAgICAgJHJlc3VsdEV4cFtdID0gd29yZCgkbnVtYmVyLCAkcnVibGVzKTsKICAgICAgICBicmVhazsvL9CS0YvRhdC+0LTQuNC8INC40Lcg0YbQuNC60LvQsCwg0YIu0LouINGD0LbQtSDRgNCw0YHQv9C40YHQsNC70Lgg0LLRgdC1INGG0LjRhNGA0YsKICAgIH0KfQoKZWNobyAiUmVzdWx0OiAiIC4gaW1wbG9kZSgiICIsICRyZXN1bHRFeHApIC4gIlxuIjsKPz4=