6
\$\begingroup\$

I have the following function which converts an integer (such as 103) to its string representation ("one hundred three"):

NumberToString = (function ()
    local floor, abs, num, tens, bases = math.floor, math.abs, {
        [0] = '',
        'one',
        'two',
        'three',
        'four',
        'five',
        'six',
        'seven',
        'eight',
        'nine',
        'ten',
        'eleven',
        'twelve',
        'thirteen',
        'fourteen',
        'fifteen',
        'sixteen',
        'seventeen',
        'eighteen',
        'nineteen',
        'twenty'
    }, {
        [0] = 'and',
        [3] = 'thirty',
        [4] = 'forty',
        [5] = 'fifty',
        [6] = 'sixty',
        [7] = 'seventy',
        [8] = 'eighty',
        [9] = 'ninety',
    }, {

        [10^2] = ' hundred',
        [10^3] = ' thousand',
        [10^6] = ' million'
    }
    return function(n)
        local n = floor( abs(n) )
        local str = {}
        if n > 10^6 then
            table.insert( str, NumberToString(n / 10^6)..bases[10^6] )
            n = n % 10^6
        end
        if n > 10^3 then
            table.insert( str, NumberToString(n / 10^3)..bases[10^3] )
            n = n % 10^3
        end
        if n > 10^2 then
            table.insert( str, NumberToString(n / 10^2)..bases[10^2] )
            n = n % 10^2
        end
        if num[n] then
            table.insert( str, num[n] )
        else
            table.insert( str, tens[floor(n/10)]..' '..(n % 10 > 0 and num[n % 10] or '') )
        end
        return table.concat(str, ' ')
    end
end)()

Can I improve the performance somehow? Or does some other (and better method) exist for the desired results?

I think that the segment between line #43 to #53 is quite redundant and can be modified?

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

After a bit of dabbling with the script, I've updated the line #42 to #53 with a table iterator:

for _, ext in ipairs(bases) do
    if n > ext[1] then
        table.insert( str, NumberToString(n / ext[1])..ext[2] )
        n = n % ext[1]
    end
end

where, bases has been redefined as:

{
    { 10^12, ' trillion' },
    { 10^9, ' billion' },
    { 10^6, ' million' },
    { 10^3, ' thousand' },
    { 10^2, ' hundred' },
}

that is, in descending orders of powers of 10.

I'd welcome other suggestions as well.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.