local function stringsplit(str)
   if #str > 1 then
      return str:sub(1,1), stringsplit(str:sub(2))
   else
      return str
   end
end

-- this is shameful how long it took to write.
-- I think a better general thing would be to write it as
-- 1377 => { 1, 1, 1, 1 }
-- 1378 => { 1, 1, 1, 2 } etc. where the table is {base #cstr, base #vstr, base #cstr}

local cstr = 'bdfghjklmnprstvw'
local vstr = 'aeiou'
local cons  = { stringsplit(cstr) }
local vowel = { stringsplit(vstr) }

-- four places is 1377 (abab)  "lett"
-- five places is 7777 (babab) "7777" hahaha

local function number2string( num, which )
--   print( 'number2string', num, which == vowel and 'vowel' or 'cons' )
   if not which then
      which = cons
      num = tonumber(num) -- protect against receiving number as string, e.g, "8192" rather than 8192
   else
      if num <= 0 then return '' end
   end
   num = num - 1
   local mod = num % #which
   return (  number2string( math.floor(num/#which),
                            which == cons and vowel or cons ) .. which[mod+1] )
end

local function string2number( str, prior, which )
--   print('string2number', str, prior )
   if not str then return end
   if not string.find(cstr,str:sub(#str)) then return end -- last letter must be consonant

   prior = prior or 0
   local check = which or vstr
   local other = (check == vstr) and cstr or vstr
   local first = str:sub(1,1)
   local f = string.find(check,first)
   if f then
      local acc = (prior*#check) + f
      return (#str <= 1) and acc or string2number(str:sub(2), acc, other)
   elseif not which then
      f = string.find(other,first)
      if not f then
         return -- invalid string
      end
      local acc = prior*#other + f
      return (#str <= 1) and acc or string2number(str:sub(2),acc,check)
   end
end

local function isvalid( str )
   local len = #str
   if len < 1 then

      return false
   end
   
   -- last letter must be consonant.
   local which = cstr

   for i = len, 1, -1 do
      if not string.find(which,str:sub(i,i)) then
         return false
      end
      -- must alternate consonant->vowel->consonant->vowel etc.
      which = (which == cstr) and vstr or cstr
   end
   return true
end


--if string.find(arg[1],'%d') then
--   local n = number2string(arg[1])
--   print(n,string2number(n))
--else
--   local n = string2number(arg[1])
--   print( n, number2string(n))
--end


return { 
   to_s = number2string,
   to_i = string2number,
   isvalid = isvalid
}