Post by Guy on Aug 9, 2017 22:12:13 GMT
Gives you the names of big numbers. It feels pretty disorganized but it works!
Goes from zero to a millinillion, after that, I don't even know why you'd need the name of a number past 10^3003.
Also, once you reach past a certain number, the name becomes longer than what's actually printable, so you'll have to figure out splitting that and viewing it on your own.
Goes from zero to a millinillion, after that, I don't even know why you'd need the name of a number past 10^3003.
Also, once you reach past a certain number, the name becomes longer than what's actually printable, so you'll have to figure out splitting that and viewing it on your own.
-- Splits the number into blocks of 3
function blockSplit(str)
local t,int,dec={},str:match('(%d+).?(%d*)')
local i,d=#int,#dec
while i>3 do
t[#t+1],int,i=int:sub(i-2,i),int:sub(1,i-3),i-3
end t[#t+1]=('%03d'):format(int+0)
i,t=t,{}
if dec~='' then
while d>3 do
t[#t+1],dec,d=dec:sub(1,3),dec:sub(4,d),d-3
end t[#t+1]=('%03d'):format(dec+0)
end
return i,t
end
-- Test blockSplit
--[[
do
local t,tt=blockSplit('123456.7891')
for k,v in ipairs(t) do
print(k,v,tt[k])
end
end
--]]
-- Basic Numbers
u = { -- Units
'one','two','three',
'four','five','six',
'seven','eight','nine'
} u[0]=''
w={ -- Weirdo Angsty Teen Numbers
'eleven','twelve','thirteen',
'fourteen','fifteen','sixteen',
'seventeen','eighteen','nineteen'
} w[0]='ten'
t = { -- Tens
'ten','twenty','thirty',
'forty','fifty','sixty',
'seventy','eighty','ninety'
} t[0]=''
h = {} -- Hundreds
for i=1,9 do h[i]=u[i]..' hundred' end
h[0]=''
function convertBlock(n)
local a,b,c=n:sub(1,1)+0,n:sub(2,2)+0,n:sub(3)+0
return h[a]..
(a>0 and (b>0 or c>0) and ' ' or '')..
(b==1 and w[c] or
(t[b]..(b>1 and c>0 and '-' or '')..
u[c]))
end
-- Test Basic Number Conversion
--[[
for i=1,50 do
local n=math.random(1,999)
print(n,convertBlock(('%03d'):format(n)))
end
--]]
-- Bigger Numbers
su = { --Starting Big Units
'm','b','tr',
'quadr','quint','sext',
'sept','oct','non'
} for i=1,9 do su[i]=su[i]..'illion' end
su[-1],su[0]='','thousand'
bu = { -- Big Units
'un','duo','tre',
'quattuor','quinqua','se',
'septe','octo','nove'
} bu[0]=''
bt = { -- Big Tens
'deci','viginti','tri',
'quadra','quinqua','sexa',
'septua','octo','nona'
} for i=3,9 do bt[i]=bt[i]..'gint' end bt[0]=''
bh = { -- Big Hundreds
'c','duc','trec',
'quadring','quing','sesc',
'septing','octing','nong'
} for i=1,9 do bh[i]=bh[i]..'enti' end bh[0]=''
function getPlace(n)
if n<10 then
return su[n]
elseif n == 1000 then
return 'millinillion'
else
local t,n={},('%03d'):format(n):reverse()
for i=1,3 do t[i]=n:sub(i,i)+0 end
local function inset(num,tbl)
for i=1,#tbl do
if num == tbl[i] then return true end
end
end
local function join(a,b,c)
local j = ''
if a == 3 then
if b ~= 0 then
if inset(b,{2,3,4,5,8}) then j='s' end
else
if inset(c,{1,3,4,5,8}) then j='s' end
end
elseif a == 6 then
if b ~= 0 then
if inset(b,{2,3,4,5}) then j='s' end
if b == 8 then j='x' end
else
if inset(c,{3,4,5}) then j='s' end
if inset(c,{1,8}) then j='x' end
end
elseif a == 7 or a == 9 then
if b ~= 0 then
if inset(b,{1,3,4,5,6,7}) then j='n' end
if inset(b,{2,8}) then j='m' end
else
if inset(c,{1,2,3,4,5,6,7}) then j='n' end
if c == 8 then j='m' end
end
elseif a == 8 then
if b ~= 0 then
if b == 8 then j='-' end
else
if c == 8 then j='-' end
end
end return j
end
return
bu[t[1]]..
join(t[1],t[2],t[3])..
bt[t[2]]..
(t[2]>2 and (t[3]~=0 and 'a' or 'i') or '')..
bh[t[3]]..'llion'
end
end
-- getPlace Test
--[[
for i=1,1000 do
print(i,getPlace(i))
end
--]]
function convert(str)
if str:match('%D')~=nil and str:match('%D')~='.' then return 'Error: NAN' end
if str == '0' then return 'zero' end
if #str > 3004 then return 'Error: BFN'
elseif #str==101 then
local a,b=str:match('([1-9])(0*)')
if b==('0'):rep(100) then
return u[a+0]..' googol'
end
end
local t,int,dec={},blockSplit(str)
for i=1,#int do t[i]=convertBlock(int[i]) end
for i=#t,1,-1 do
if t[i]~='' then
t[i]=t[i]..' '..getPlace(i-2)
else table.remove(t,i)
end
end
for i=1,math.floor(#t/2) do
t[i],t[#t-i+1]=t[#t-i+1],t[i]
end
return table.concat(t,' ')
end
-- To test it out
while true do
print('\nType a big number')
local n=io.read()
print()
print(n:reverse():gsub('%d%d%d','%1,',math.ceil(#n/3)-1):reverse())
print(convert(n))
end