Module:Converters

From Pathfinder Wiki
Revision as of 14:10, 14 March 2022 by DesignerThan (talk | contribs)

Documentation for this module may be created at Module:Converters/doc

local p = {}

function p.NumToAlphabet(num)
	if (type(num) == 'string') then
		num = tonumber(num)
	end
	if (type(num) ~= 'number') then
		error"Invalid Input! Not able to convert to Alphabet."
	end
	local letterCount = 1
	while (num > 26) do
		letterCount = letterCount + 1
		num = num - 26
	end
	local output = ''
	for i=1,letterCount do
		output = output..string.char(string.byte("a")+num-1)
	end
	return output
end
function p.FNumToAlphabet(frame)
	return p.NumToAlphabet(frame.args[1])
end

function p.AlphabetToNum(s)
	s = s:lower()
	mw.log('Converters.AlphabetToNum (s): '..s)
	mw.log('Converters.AlphabetToNum (s:len()): '..s:len())
	local c = s:sub(1, 1)
	mw.log('Converters.AlphabetToNum (s:len()): '..s:len())
	return (string.byte(c)-string.byte("a")+1)*tonumber(s:len())
end
function p.FAlphabetToNum(frame)
	return p.AlphabetToNum(frame.args[1])
end

-- https://gist.github.com/efrederickson/4080372
local map = { 
    I = 1,
    V = 5,
    X = 10,
    L = 50,
    C = 100, 
    D = 500, 
    M = 1000,
}
local numbers = { 1, 5, 10, 50, 100, 500, 1000 }
local chars = { "I", "V", "X", "L", "C", "D", "M" }

function p.NumToRoman(s)
    --s = tostring(s)
    s = tonumber(s)
    if not s or s ~= s then error"Unable to convert to number" end
    if s == math.huge then error"Unable to convert infinity" end
    s = math.floor(s)
    if s <= 0 then return s end
	local ret = ""
        for i = #numbers, 1, -1 do
        local num = numbers[i]
        while s - num >= 0 and s > 0 do
            ret = ret .. chars[i]
            s = s - num
        end
        --for j = i - 1, 1, -1 do
        for j = 1, i - 1 do
            local n2 = numbers[j]
            if s - (num - n2) >= 0 and s < num and s > 0 and num - n2 ~= n2 then
                ret = ret .. chars[j] .. chars[i]
                s = s - (num - n2)
                break
            end
        end
    end
    return ret
end
function p.FNumToRoman(frame)
	return p.NumToRoman(frame.args[1])
end

function p.RomanToNum(s)
    s = s:upper()
    local ret = 0
    local i = 1
    while i <= s:len() do
    --for i = 1, s:len() do
        local c = s:sub(i, i)
        if c ~= " " then -- allow spaces
            local m = map[c] or error("Unknown Roman Numeral '" .. c .. "'")
            
            local next = s:sub(i + 1, i + 1)
            local nextm = map[next]
            
            if next and nextm then
                if nextm > m then 
                -- if string[i] < string[i + 1] then result += string[i + 1] - string[i]
                -- This is used instead of programming in IV = 4, IX = 9, etc, because it is
                -- more flexible and possibly more efficient
                    ret = ret + (nextm - m)
                    i = i + 1
                else
                    ret = ret + m
                end
            else
                ret = ret + m
            end
        end
        i = i + 1
    end
    return ret
end
function p.FRomanToNum(frame)
	return p.RomanToNum(frame.args[1])
end




return p