Moduł:Sandbox/Draco flavus/Liczebniki

Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Sandbox/Draco flavus/Liczebniki/opis

local p = {}

function p.partitions(frame)
	-- returns 
	-- Abd:Def/Ghi/Jkl mno  → Abd:Def/Ghi | Jkl mno | ø | 0 | no
	-- Abd:Def/Ghi/Jkl dwudziesty pierwszy → Abd:Def/Ghi/ | Jkl␣ | dwudziesty pierwszy | 21 | ordinal
	-- Abd:Def/Ghi/Jkl XXI → Abd:Def/Ghi/ | Jkl␣ | XXI | 21 | rom
	-- Abd:Def/Ghi/XXI → Abd:Def/Ghi/ | ø | XXI | 21 | rom
	-- Abd:Def/Ghi/Jkl 21 → Abd:Def/Ghi/ | Jkl␣ | 21 | 21 | dec
	-- Abd:Def/Ghi/Jkl21 → Abd:Def/Ghi/ | Jkl | 21 | 21 | dec
	-- Abd:Def/Ghi/21 → Abd:Def/Ghi/ | ø | 21 | 21 | dec
	-- Abd:Jkl 21 → ø | Abd:Jkl␣ | 21 | 21 | dec
	
	a = 'Abd:Jkl 21'
	local lastslashpos = (a:reverse()):find('/') or 0
    -- return (a:sub(1 - lastslashpos))
    return (a:sub(1, lastslashpos))
end
function p.pbn(frame)
	-- returns 
	-- Abd:Def/Ghi/Jkl mno  → Abd:Def/Ghi | Jkl mno | ø | 0 | ø | ø | no
	-- Abd:Def/Ghi/Jkl dwudziesty pierwszy → Abd:Def/Ghi/ | Jkl␣ | dwudziesty pierwszy | 21 | dwudziesty | dwudziesty drugi | ordinal
	-- Abd:Def/Ghi/Jkl XXI → Abd:Def/Ghi/ | Jkl␣ | XXI | 21 | XX | XXII | rom
	-- Abd:Def/Ghi/XXI → Abd:Def/Ghi/ | ø | XXI | 21 | XX | XXII | rom
	-- Abd:Def/Ghi/Jkl 21 → Abd:Def/Ghi/ | Jkl␣ | 21 | 21 | 20 | 22 | dec
	-- Abd:Def/Ghi/Jkl21 → Abd:Def/Ghi/ | Jkl | 21 | 21 | 20 | 22 | dec
	-- Abd:Def/Ghi/21 → Abd:Def/Ghi/ | ø | 21 | 21 | 20 | 22 | dec
	-- Abd:Jkl 21 → ø | Abd:Jkl␣ | 21 | 21 | 20 | 22 | dec
	a = frame.args[1]
	local lastslashpos = (a:reverse()):find('/') or 0
    -- return (a:sub(1 - lastslashpos))
    poz = a:find('%d+$')                                             -- czy na końcu cyfra
	if poz == nil then
		-- na końcu nie ma cyfry (rzymskie, słowne lub nienumeryczne)
		poz = a:find('[MDCLXVI]+$')                                  -- czy na końcu rzymskie
		if poz == nil then
			-- na końcu nie ma cyfry ani rzymskiej (słowne lub nienumeryczne)
			num = porzadkowe2dec(a)
			gen = a:sub(-1, -1)
			regen = porzadkowe(num, gen)
			poz = a:find(' ' .. regen .. '$')
			if poz == nil or lastslashpos == poz - 1 then                                       -- czy na końcu liczebnik (słownie)
				-- nie jest to numeryczne
				b = a .. '@' .. 'ø' .. '@' .. 0 .. '@' .. 'ø' .. '@' .. 'ø' .. 'no'
				else
				-- na końcu liczebnik porządkowy
				b = a:sub(1,poz) .. '@' .. regen .. '@' ..  num .. '@' .. porzadkowe(num - 1, gen) .. '@' .. porzadkowe(num + 1, gen) .. '@' .. 'ordinal'
			end	
		else
			-- na końcu rzymskie
			num = HighRoman2dec(a:sub(poz))
			regen = HighRoman(num)
			if (a:sub(poz - 1, poz - 1) == ' ' or a:sub(poz - 1, poz - 1) == '/') and regen == a:sub(poz) then
				b = a:sub(1, poz - 1) .. '@' .. regen .. '@' ..  num .. '@' .. HighRoman(num - 1) .. '@' .. HighRoman(num + 1) .. '@' .. 'roman'
			else
				b = a .. '@' .. 'ø' .. '@' .. 0 .. '@' .. 'ø' .. '@' .. 'ø' .. 'NO'
			end
		end
	else
		-- na końcu cyfry
		num = tonumber(a:sub(poz))
		b = a:sub(1, poz - 1) .. '@' .. num .. '@' ..  num .. '@' .. num - 1 .. '@' .. num + 1 .. '@' .. 'numeric'
	end
	return b
end
function p.partitions2(frame)
	--a = 'Rozdział dwa tysiące dwudziesty siódmy'
	--a = 'Coś tam coś tam'
	--a = 'Rozdział lub część II'
	--a = 'CXVI'
	--a = 'Rozdział lub część 23'
	-- a = 'Rozdział-24'
	-- a = '25'
	a = frame.args[1]
	poz = a:find('%d+$')                                             -- czy na końcu cyfra
	if poz == nil then
		-- na końcu nie ma cyfry (rzymskie, słowne lub nienumeryczne)
		poz = a:find('[MDCLXVI]+$')                                  -- czy na końcu rzymskie
		if poz == nil then
			-- na końcu nie ma cyfry ani rzymskiej (słowne lub nienumeryczne)
			slow = porzadkowe(porzadkowe2dec(a),a:sub(-1, -1))
			poz = a:find(' ' .. slow .. '$')
			if poz == nil then                                       -- czy na końcu liczebnik (słownie)
				-- nie jest to numeryczne
				b = 'nienumeryczny '.. '@' .. '' .. '@'.. a .. '@'.. a:len() .. '@'.. 'nil' ..a:sub(-1, -1)
			else
				-- na końcu liczebnik porządkowy
				b = 'porządkowy' .. '@'.. a:sub(1, poz) .. '@'.. a:sub(poz + 1) .. '@'.. a:len() .. '@'.. poz + 1
			end	
		else
			-- na końcu rzymskie
			if poz == 1 then
				b = 'same rzymskie'.. '@'.. '' .. '@'.. a .. '@'.. a:len() .. '@'.. poz
			else
				if a:sub(poz - 1, poz - 1) == ' ' then
					b = 'rzymskie poprzedzone prefiksem'.. '@'..a:sub(1, poz - 1) .. '@'.. a:sub(poz) .. '@'.. a:len() .. '@'.. poz
				else
					b = 'inne (nienumeryczne)'.. '@'..'' .. '@'.. a .. '@'.. a:len() .. '@'.. poz .. a:sub(-1, -1)
				end
			end
		end
	else
		-- na końcu cyfry
		if poz == 1 then
			b = 'same cyfry'.. '@'.. '' .. '@'.. a .. '@'.. a:len() .. '@'.. poz
		else
			b = 'cyfry z prefiksem'.. '@'..a:sub(1, poz-1) .. '@'.. a:sub(poz) .. '@'.. a:len() .. '@'.. poz
		end
	end
	return b
end
function p.tes(frame)
	a = tonumber(frame.args[1])
	return a .. ' ' .. porzadkowe(a,'y') .. ' ' .. porzadkowe(a,'a') .. ' ' .. porzadkowe(a,'e') .. ' ' .. tostring(porzadkowe2dec(porzadkowe(a,'y')) == porzadkowe2dec(porzadkowe(a,'a')) and porzadkowe2dec(porzadkowe(a,'y')) == porzadkowe2dec(porzadkowe(a,'e')) and porzadkowe2dec(porzadkowe(a,'y')) == a and HighRoman2dec(HighRoman(a)) == a) .. ' ' .. HighRoman(a)
end
function p.poprzedni(frame)
	a = frame.args[1]
	local lastslashpos = (a:reverse()):find('/') or 0
    -- return (a:sub(1 - lastslashpos))
    poz = a:find('%d+$')                                             -- czy na końcu cyfra
	if poz == nil then
		-- na końcu nie ma cyfry (rzymskie, słowne lub nienumeryczne)
		poz = a:find('[MDCLXVI]+$')                                  -- czy na końcu rzymskie
		if poz == nil then
			-- na końcu nie ma cyfry ani rzymskiej (słowne lub nienumeryczne)
			num = porzadkowe2dec(a)
			gen = a:sub(-1, -1)
			regen = porzadkowe(num, gen)
			poz = a:find(' ' .. regen .. '$')
			if poz == nil or lastslashpos == poz - 1 then                                       -- czy na końcu liczebnik (słownie)
				-- nie jest to numeryczne
				b = a
				else
				-- na końcu liczebnik porządkowy
				b = a:sub(1,poz) .. porzadkowe(num - 1, gen)
			end	
		else
			-- na końcu rzymskie
			num = HighRoman2dec(a:sub(poz))
			regen = HighRoman(num)
			if (a:sub(poz - 1, poz - 1) == ' ' or a:sub(poz - 1, poz - 1) == '/') and regen == a:sub(poz) then
				b = a:sub(1, poz - 1) .. HighRoman(num - 1)
			else
				b = a
			end
		end
	else
		-- na końcu cyfry
		num = tonumber(a:sub(poz))
		b = a:sub(1, poz - 1) .. num - 1
	end
	return b
end
function p.biezacy(frame)
	a = frame.args[1]
	local lastslashpos = (a:reverse()):find('/') or 0
    -- return (a:sub(1 - lastslashpos))
    poz = a:find('%d+$')                                             -- czy na końcu cyfra
	if poz == nil then
		-- na końcu nie ma cyfry (rzymskie, słowne lub nienumeryczne)
		poz = a:find('[MDCLXVI]+$')                                  -- czy na końcu rzymskie
		if poz == nil then
			-- na końcu nie ma cyfry ani rzymskiej (słowne lub nienumeryczne)
			num = porzadkowe2dec(a)
			gen = a:sub(-1, -1)
			regen = porzadkowe(num, gen)
			poz = a:find(' ' .. regen .. '$')
			if poz == nil or lastslashpos == poz - 1 then                                       -- czy na końcu liczebnik (słownie)
				-- nie jest to numeryczne
				b = a
				else
				-- na końcu liczebnik porządkowy
				b = num
			end	
		else
			-- na końcu rzymskie
			num = HighRoman2dec(a:sub(poz))
			regen = HighRoman(num)
			if (a:sub(poz - 1, poz - 1) == ' ' or a:sub(poz - 1, poz - 1) == '/') and regen == a:sub(poz) then
				b = num
			else
				b = a
			end
		end
	else
		-- na końcu cyfry
		num = tonumber(a:sub(poz))
		b = num
	end
	return b
end
function p.nastepny(frame)
	a = frame.args[1]
	local lastslashpos = (a:reverse()):find('/') or 0
    -- return (a:sub(1 - lastslashpos))
    poz = a:find('%d+$')                                             -- czy na końcu cyfra
	if poz == nil then
		-- na końcu nie ma cyfry (rzymskie, słowne lub nienumeryczne)
		poz = a:find('[MDCLXVI]+$')                                  -- czy na końcu rzymskie
		if poz == nil then
			-- na końcu nie ma cyfry ani rzymskiej (słowne lub nienumeryczne)
			num = porzadkowe2dec(a)
			gen = a:sub(-1, -1)
			regen = porzadkowe(num, gen)
			poz = a:find(' ' .. regen .. '$')
			if poz == nil or lastslashpos == poz - 1 then                                       -- czy na końcu liczebnik (słownie)
				-- nie jest to numeryczne
				b = a
				else
				-- na końcu liczebnik porządkowy
				b = a:sub(1,poz) .. porzadkowe(num + 1, gen)
			end	
		else
			-- na końcu rzymskie
			num = HighRoman2dec(a:sub(poz))
			regen = HighRoman(num)
			if (a:sub(poz - 1, poz - 1) == ' ' or a:sub(poz - 1, poz - 1) == '/') and regen == a:sub(poz) then
				b = a:sub(1, poz - 1) .. HighRoman(num + 1)
			else
				b = a
			end
		end
	else
		-- na końcu cyfry
		num = tonumber(a:sub(poz))
		b = a:sub(1, poz - 1) .. num + 1
	end
	return b
end
function porzadkowe2dec(str)
	local b = 0
	local c = ''
	local liczebniki = {['tysięczn'] = 1000, ['dwutysięczn'] = 2000, ['trzytysięczn'] = 3000, ['tysią'] = 1000, ['dw'] = 2000, ['trz'] = 3000, ['setn'] = 100, ['dwusetn'] = 200, ['trzysetn'] = 300, ['czterysetn'] = 400, ['pięćsetn'] = 500, ['sześćsetn'] = 600, ['siedemsetn'] = 700, ['osiemsetn'] = 800, ['dziewięćsetn'] = 900, ['st'] = 100, ['dwieści'] = 200, ['trzyst'] = 300, ['czteryst'] = 400, ['pięćse'] = 500, ['sześćse'] = 600, ['siedemse'] = 700, ['osiemse'] = 800, ['dziewięćse'] = 900, ['pierwsz'] = 1, ['drugi'] = 2, ['drug'] = 2, ['trzeci'] = 3, ['trzec'] = 3, ['czwart'] = 4, ['piąt'] = 5, ['szóst'] = 6, ['siódm'] = 7, ['ósm'] = 8, ['dziewiąt'] = 9, ['dziesiąt'] = 10, ['jedenast'] = 11, ['dwunast'] = 12, ['trzynast'] = 13, ['czternast'] = 14, ['piętnast'] = 15, ['szesnast'] = 16, ['siedemnast'] = 17, ['osiemnast'] = 18, ['dziewiętnast'] = 19, ['dwudziest'] = 20, ['trzydziest'] = 30, ['czterdziest'] = 40, ['pięćdziesiąt'] = 50, ['sześćdziesiąt'] = 60, ['siedemdziesiąt'] = 70, ['osiemdziesiąt'] = 80, ['dziewięćdziesiąt'] = 90}  
	for t in string.gmatch(str, "([^"..' '.."]+)") do
		c = c .. '@' .. string.sub(t, 1, -2)
        b = b + tonumber(liczebniki[string.sub(t, 1, -2)] or 0)
	end
	return b
end

function porzadkowe(num, rodzaj)
	local fullthousends = {'tysięczn', 'dwutysięczn', 'trzytysięczn'}
	local thousends = {'tysiąc ', 'dwa tysiące ', 'trzy tysiące '}
	local fullhundreds = {'setn', 'dwusetn', 'trzysetn', 'czterysetn', 'pięćsetn', 'sześćsetn', 'siedemsetn', 'osiemsetn', 'dziewięćsetn'}
	local hundreds = {'sto ', 'dwieście ', 'trzysta ', 'czterysta ', 'pięćset ', 'sześćset ', 'siedemset ', 'osiemset ', 'dziewięćset '}
	local onetonineteen = {'pierwsz', 'drugi', 'trzeci', 'czwart', 'piąt', 'szóst', 'siódm', 'ósm', 'dziewiąt', 'dziesiąt', 'jedenast', 'dwunast', 'trzynast', 'czternast', 'piętnast', 'szesnast', 'siedemnast', 'osiemnast', 'dziewiętnast'}
	local smallnumerals
	local tens = {'dziesiąt', 'dwudziest', 'trzydziest', 'czterdziest', 'pięćdziesiąt', 'sześćdziesiąt', 'siedemdziesiąt', 'osiemdziesiąt', 'dziewięćdziesiąt'}
	local k
	local r = {}
	if rodzaj == 'i' then 
		rodzaj = 'y'
	end
	local sdj = num % 1000
	local t = (num - sdj) / 1000
	local dj = sdj % 100
	local s = (sdj - dj) / 100
	local j = dj % 10
	local d = (dj - j) / 10
	if num < 1 or num > 3999 then
		return 'error'
	else
		if sdj == 0 then
			r[1] = fullthousends[t]
			r[2] = rodzaj
		else
			if t == 0 then
				r[1] = ''
			else
				r[1] = thousends[t]
			end
			if dj == 0 then
				r[2] = fullhundreds[s]
				if s == 0 then
					r[3] = ''
				else
					r[3] = rodzaj
				end
			else
				if s == 0 then
					r[2] = ''
				else
					r[2] = hundreds[s]
				end
				if dj >= 10 and dj <= 19 then
					r[3] = onetonineteen[dj]
					r[4] = rodzaj
				else
					if dj < 10 then
						r[3] = ''
						r[4] = ''
					else
						r[3] = tens[d]
						if j == 0 then
							r[4] = rodzaj
						else
							r[4] = rodzaj .. ' '
						end
					end
					if j == 0 then
						r[5] = ''
					else
						r[5] = onetonineteen[j]
						r[6] = rodzaj
					end
					if r[6] == 'y' and (r[5] == 'drugi' or r[5] == 'trzeci') then
						r[6] = ''
					end
					if r[6] == 'a' and r[5] == 'drugi' then
						r[5] = 'drug'
					end
				end
			end	
		end
	end
	return table.concat(r,'')
end

function p.main(frame)
	a = frame.args[1]
	return HighRoman(a) .. '  ' .. porzadkowe(a, 'y')  .. '  ' .. porzadkowe(a, 'a')  .. '  ' .. porzadkowe(a, 'e') .. ' ' .. tostring(HighRoman2dec(HighRoman(a)) == a and porzadkowe(a, 'y') == porzadkowe(a, 'i') and porzadkowe2dec(porzadkowe(a, 'y')) == a and porzadkowe2dec(porzadkowe(a, 'a')) == a and porzadkowe2dec(porzadkowe(a, 'e')) == a)
end

local HighRomans = {
    { 1000, 'M' },
    { 900, 'CM' }, { 500, 'D' }, { 400, 'CD' }, { 100, 'C' },
    {  90, 'XC' }, {  50, 'L' }, {  40, 'XL' }, {  10, 'X' },
    {   9, 'IX' }, {   5, 'V' }, {   4, 'IV' }, {   1, 'I' }
}


function HighRoman(num)
    local ret = {}
    for _, v in ipairs(HighRomans) do
        local val, letter = unpack(v)
        while num >= val do
            num = num - val
            table.insert(ret, letter)
        end
    end
    return table.concat(ret)
end

local HighRomans2dec = {['M'] = 1000, ['D'] = 500, ['C'] = 100, ['L'] = 50, ['X'] = 10, ['V'] = 5, ['I'] = 1 }

function HighRoman2dec(str)
    local ret = '0'
    local actsign = '0'
    local lastsign = 0
    local i = 1
	for i = #str, 1, -1 do
		actsign = HighRomans2dec[str:sub(i,i)]
		ret = ret + (actsign < lastsign and -actsign or actsign)
		lastsign = actsign
	end
	return ret
end

return p