How does one change an integer into a string?

Now, hear me out here.
Given an index “i”, between 1 and 9, is there any function to convert that number into a string whilst also using the number’s name?
For example, if I had the index “4”, and ran this function upon it, I would receive and output of “four”, as opposed to “4”, just in string form.
I mean, I can easily do some ugly if-statements, but no-one likes a long, repetitive list of if-statements.

Thanks,
CyroStorms

2 Likes

You can use this table instead of the if statements,

Word2Number={
    ["zero"]=0,
    ["one"]=1,
    ["two"]=2,
    ["three"]=3,
    ["four"]=4,
    ["five"]=5,
    ["six"]=6,
    ["seven"]=7,
    ["eight"]=8,
    ["nine"]=9,
    ["ten"]=10,
    ["eleven"]=11,
    ["twelve"]=12,
    ["thirteen"]=13,
    ["fourteen"]=14,
    ["fifteen"]=15,
    ["sixteen"]=16,
    ["seventeen"]=17,
    ["eighteen"]=18,
    ["nineteen"]=19,
    ["twenty"]=20,
    ["twenty-one"]=21,
    ["twenty-two"]=22,
    ["twenty-three"]=23,
    ["twenty-four"]=24,
    ["twenty-five"]=25,
    ["twenty-six"]=26,
    ["twenty-seven"]=27,
    ["twenty-eight"]=28,
    ["twenty-nine"]=29,
    ["thirty"]=30,
    ["thirty-one"]=31,
    ["thirty-two" ]=32,
    ["thirty-three" ]=33,
    ["thirty-four"]=34,
    ["thirty-five"]=35,
    ["thirty-six"]=36,
    ["thirty-seven"]=37,
    ["thirty-eight"]=38,
    ["thirty-nine"]=39,
    ["forty"]=40,
    ["forty-one"]=41,
    ["forty-two"]=42,
    ["forty-three"]=43,
    ["forty-four"]=44,
    ["forty-five"]=45,
    ["forty-six"]=46,
    ["forty-seven"]=47,
    ["forty-eight"]=48,
    ["forty-nine"]=49,
    ["fifty"]=50,
}
2 Likes

Fair point, that’s a good idea.
Thanks!

There’s a pattern in the numbers’ name:

  • 1 to 19 should be fixed
    • 13 to 15 uses prefix of the ordinal number(minus some letters) and the suffix “-teen”
    • 16 to 19 uses suffix of “-teen”
  • 20 and beyond gives you a combination of their number + the singular; twenty and one
  • 100 and beyond with the similar logic above
1 Like

I have made a better function instead of typing every number.

local floor = math.floor
local num = {{'one', 1}, {'two', 2}, {'three', 3}, {'four', 4}, {'five', 5}, {'six', 6}, {'seven', 7}, {'eight', 8}, {'nine', 9}, {'ten', 10}, {'eleven', 11},
   {'twelve', 12}, {'thirteen', 13}, {'fourteen', 14}, {'fifteen', 15}, {'sixteen', 16}, {'seventeen', 17}, {'eighteen', 18}, {'nineteen', 19}}
local tens = {{'twenty', 20}, {'thirty', 30}, {'forty', 40}, {'fifty', 50}, {'sixty', 60}, {'seventy', 70}, {'eighty', 80}, {'ninety', 90}}
local bases = {{floor(1e18), ' quintillion'}, {floor(1e15), ' quadrillion'}, {floor(1e12), ' trillion'},
   {' billion', floor(1e9)}, {' million', 1000000}, {' thousand', 1000}, {' hundred', 100}}


function wordToNumber(word)
	for i,v in pairs(tens) do
		for x,d in pairs(num) do
			if word == num[x][1] then
				return num[x][2]
			end
			if word == tens[i][1] then
				return tens[i][2]
			end
		    if word == tens[i][1].."-"..num[x][1] then
			   return tens[i][2]+num[x][2]
		    end
		for z,b in pairs(bases) do
		    if word == num[x][1]..bases[z][1] then
			return num[x][2] * bases[z][2]
		    end
		    if word == tens[i][1]..bases[z][1] then
			return tens[i][2] * bases[z][2]
		    end
		    if word == tens[i][1].."-"..num[x][1]..bases[z][1] then
			return (tens[i][2] + num[x][2]) * bases[z][2]
		    end
		end
		end
	end
end

print(wordToNumber("twenty-one million"))
print(wordToNumber("one million"))
print(wordToNumber("fifty-one"))
print(wordToNumber("thirty"))
print(wordToNumber("six"))
1 Like

This would work until 999 billion

2 Likes

Sorry, this would work better with numbers over 100:

local floor = math.floor
local num = {{'one', 1}, {'two', 2}, {'three', 3}, {'four', 4}, {'five', 5}, {'six', 6}, {'seven', 7}, {'eight', 8}, {'nine', 9}, {'ten', 10}, {'eleven', 11},
   {'twelve', 12}, {'thirteen', 13}, {'fourteen', 14}, {'fifteen', 15}, {'sixteen', 16}, {'seventeen', 17}, {'eighteen', 18}, {'nineteen', 19}}
local tens = {{'twenty', 20}, {'thirty', 30}, {'forty', 40}, {'fifty', 50}, {'sixty', 60}, {'seventy', 70}, {'eighty', 80}, {'ninety', 90}}
local bases = {{floor(1e18), ' quintillion'}, {floor(1e15), ' quadrillion'}, {floor(1e12), ' trillion'},
   {' billion', floor(1e9)}, {' million', 1000000}, {' thousand', 1000}, {' hundred', 100}}
function wordToNumber(word)
	for i,v in pairs(tens) do
		for x,d in pairs(num) do
			if word == num[x][1] then
				return num[x][2]
			end
			if word == tens[i][1] then
				return tens[i][2]
			end
		    if word == tens[i][1].."-"..num[x][1] then
			   return tens[i][2]+num[x][2]
		    end
		for z,b in pairs(bases) do
		    if word == num[x][1]..bases[z][1] then
			return num[x][2] * bases[z][2]
		    end
		    if word == tens[i][1]..bases[z][1] then
			return tens[i][2] * bases[z][2]
		    end
		    for h,a in pairs(num) do
		    if word == num[x][1]..bases[z][1].." "..num[h][1] then
			return (num[x][2] * bases[z][2]) + num[h][2]
		    end
		    end
		    if word == tens[i][1].."-"..num[x][1]..bases[z][1] then
			return (tens[i][2] + num[x][2]) * bases[z][2]
		    end
		end
		end
	end
end
print(wordToNumber("twenty-one million"))

print(wordToNumber("one million"))

print(wordToNumber("fifty-one"))

print(wordToNumber("thirty"))

print(wordToNumber("six"))

print(wordToNumber("five hundred"))

print(wordToNumber("five hundred five"))

I think you’re misreading the question. OP wants numbers (1, 2, 3, …) as the input and english words (one, two, three) as the output. Your solutions take english words as input and numbers as output.

The accepted answer did get the right idea though. Just using a table that maps the numbers to their names is good enough. OP also said that the input only ranges from 1-9. Doing work more than this isn’t really necessary.

Oh sorry for misreading your question.

local append, concat, floor, abs = table.insert, table.concat, math.floor, math.abs
local num = {'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
   'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'}
local tens = {'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'}
local bases = {{floor(1e18), ' quintillion'}, {floor(1e15), ' quadrillion'}, {floor(1e12), ' trillion'},
   {floor(1e9), ' billion'}, {1000000, ' million'}, {1000, ' thousand'}, {100, ' hundred'}}

local insert_word_AND = false  -- 101 = "one hundred and one" / "one hundred one"

local function IntegerNumberInWords(n)
   -- Returns a string (spelling of integer number n)
   -- n should be from -2^53 to 2^53  (-2^63 < n < 2^63 for integer argument in Lua 5.3)
   local str = {}
   if n < 0 then
      append(str, "minus")
   end
   n = floor(abs(n))
   if n == 0 then
      return "zero"
   end
   if n >= 1e21 then
      append(str, "infinity")
   else
      local AND
      for _, base in ipairs(bases) do
         local value = base[1]
         if n >= value then
            append(str, IntegerNumberInWords(n / value)..base[2])
            n, AND = n % value, insert_word_AND or nil
         end
      end
      if n > 0 then
         append(str, AND and "and")   -- a nice pun !
         append(str, num[n] or tens[floor(n/10)-1]..(n%10 ~= 0 and '-'..num[n%10] or ''))
      end
   end
   return concat(str, ' ')
end

print(IntegerNumberInWords(1000))
print(IntegerNumberInWords(120))

Here is the correct code.

2 Likes