Module:MathRoman: Difference between revisions
From Guild of Archivists
(adapter http://scribunto.wmflabs.org/index.php/Module_talk:MathRoman.lua) |
m (1 revision imported) |
Latest revision as of 07:26, 30 October 2015
Documentation for this module may be created at Module:MathRoman/doc
--[[ 20120505 19:50 calcul de nombre romain pour http://fr.wikisource.org/
script en langage LUA, exemples d'appels :
valeurDeRomain('MCXI')
testerDesRomains('vue') parametre obsolete
http://phrogz.net/Lua/LearningLua_FromJS.html Learning Lua/From JS
http://www.lua.org/pil/ Programming in Lua reference
http://www.lua.org/cgi-bin/demo Demo Try Lua
20120503 22:16 tests partiel OK
20120504 22:57 tests complets. Your program ran successfully.
20120505 00:10 adapter a Module:mathRoman.lua
http://www.mediawiki.org/wiki/Module:mathRoman.lua
http://www.mediawiki.org/wiki/Extension:Scribunto/Parser_interface_design
Proposed interface summary
20120505 19:50 function r.roman2integer( frame )
]]--
function roman2int(rm, err)
if ( rm == nil ) then rm = '' end
if ( err == nil ) then err = '' end
if ( rm == '' ) then return '' end
local v = 0 -- valeur totale
local v1 = 0 -- valeur de derniere lettre
local v2 = 0 -- valeur de lettre precedente
local v3 = 0 -- valeur de lettre precedente
local x = '-' -- caractere en cours d'evaluation
local i = 0 -- numéro du caractere en cours d'evaluation
local j = 0 -- numéro du caractere de reference courant (debut en Lua)
local k = 0 -- numéro du caractere de reference courant (fin en Lua)
local e0 = '' -- texte d'erreur
local e1 = '' -- texte d'erreur
local e2 = '' -- texte d'erreur
local e3 = '' -- texte d'erreur
local e4 = '' -- texte d'erreur
local lst = '-MDCLXVIJ' -- caracteres autorises
while (x ~= '') do
v3 = v2
v2 = v1
v1 = 0
x = string.sub(rm, i, i)
if ( x == 'M' ) then v1 = 1000 end
if ( x == 'D' ) then v1 = 500 end
if ( x == 'C' ) then v1 = 100 end
if ( x == 'L' ) then v1 = 50 end
if ( x == 'X' ) then v1 = 10 end
if ( x == 'V' ) then v1 = 5 end
if ( x == 'I' ) then v1 = 1 end
if ( x == 'J' ) then
v1 = 1
if ( i < ( string.len(rm) - 0 ) )
then e4 = ' erreur caractere J avant la fin.' end
end
v = v + v1
if ( (v1 == 5*v2) or (v1 == 10*v2) ) then v = v - (2*v2) end -- ajuster 4, 9, 40, 90 ...
j, k = string.find(lst, x)
if ( j == nil ) then j = -1 end
if ( k == nil ) then k = -1 end
if ( j < 1 ) then e3 = ' erreur caractere '..x..' en '..i..'.' end
if ( (v1 > v2) and (v2 > v3) ) then e2 = ' caracteres croissants.' end
i = i + 1
x = string.sub(rm, i, i)
end
if ( v == 0 ) then e0 = ' valeur nulle.' end
if ( v > 4999 ) then e1 = ' valeur > 4999.' end
if ( ( e0..e1..e2..e3..e4 > '' ) and ( err > '' ) ) then
err = ''..err..e0..e1..e2..e3..e4 -- sortie avec les erreurs
else
err = '' -- sortie sans les erreurs
end
return v, err -- avec ou sans erreurs
end -- function roman2int(rm, err)
function romani2r(i, j)
if ( j == nil ) then j = '' end
local rm=''
if ( i == 1000 ) then rm = 'M' end
if ( i == 500 ) then rm = 'D' end
if ( i == 100 ) then rm = 'C' end
if ( i == 50 ) then rm = 'L' end
if ( i == 10 ) then rm = 'X' end
if ( i == 5 ) then rm = 'V' end
if ( i == 1 ) then
rm = 'I'
if ( j == 'J' ) then rm = 'J' end
end
return rm
end -- function romani2r(i, j)
function int2roman(i, err)
local n = 0
if ( i == nil ) then n = 0 else n = i end -- anti null
if ( type(n) ~= 'number' ) then n = tonumber(n) end
if ( type(n) ~= 'number' ) then n = 0 end
n = math.floor(n) -- input:89: bad argument #1 to 'floor' (number expected, got nil)
-- if ( type (v) ~= 'number' ) then i = 0 end -- anti nil
-- i = i.valueOf()
if ( err == nil ) then err = ' ' end -- anti null, to text
local v100 = 100
local v500 = v100*5
local v1000 = v100*10 -- cycle romain 1000, 100, 10, 1
local v=0
local v1=0
local v2=0
local v3=0 -- valeurs totale, derniere, et precedentes
local reste=0
local reduction=0 -- reste a convertir, derniere reduction
--local x='-' local i=0 -- caractere courant et son numéro
--local lst='-MDCLXVIJ' -- liste des chiffres romains
local rm=''
local roman='' -- chiffre et nombre romain resultant
local e0=''
local e1=''
local e2=''
local e3=''
local e4='' -- erreurs detectables
if ( n > 4999 ) then
e1 = ' valeur > 4999.'
roman = 'ERREUR'
n = 0
end
if ( n < 1 ) then
e2 = ' valeur < 1.'
roman = 'ERREUR'
n = 0
end
reste = n
-- return ' test ' -- temporaire
while (reste > 0) do
v3 = v2
v2 = v1
v1 = reste
reduction = 0
if ( reste >= v1000 ) then
reduction = v1000
elseif ( reste >= v100*9 ) then
reduction = v100
reste = reste + v100*2
elseif ( reste >= v500 ) then
reduction = v500
elseif ( reste >= v100*4 ) then
reduction = v100
reste = reste + v100*2
elseif ( reste >= v100 ) then
reduction = v100
elseif ( reste >= 1000 ) then
v100 = 100
v1000 = 1000
reduction = v1000
end
rm = romani2r(reduction)
roman = roman..rm
reste = reste - reduction
if ( reste < v100 ) then
if ( v100 >= 10 ) then
v100 = v100/10
v500 = v100*5
v1000 = v100*10
end
end
end
-- if ( v == 0 ) then e0 = ' valeur nulle.' end
-- if ( v > 4999 ) then e1 = ' valeur > 4999.' end
if ( ( e0..e1..e2..e3..e4 > '' ) and ( err > '' ) ) then
err = ''..err..e0..e1..e2..e3..e4 -- sortie avec les erreurs
else
err = '' -- sortie sans les erreurs
end
return roman, err -- avec ou sans erreurs
end -- function int2roman(in, err)
function testerUnRomain(r1, view)
if ( r1 == nil ) then r1 = '' end
if ( view == nil ) then view = '' end
if ( view == '' ) then view = '%s' end
local i, erri = roman2int(r1, ' Erreur r2i : ')
local rm, errm = int2roman(i, ' Erreur i2r : ')
local s = r1 .. '=' .. i .. '=' .. rm
if ( erri == nil ) then erri = '' end
if ( errm == nil ) then errm = '' end
if ( ( erri ~= '' ) or ( errm ~= '' ) ) then
s = s .. ' -> ' .. erri .. errm
end
return string.format(view, s)
-- return string.format("Hello, %s!", s)
end -- function testerUnRomain(r1, view)
function erreurUnRomain(r1, view)
if ( r1 == nil ) then r1 = '' end
if ( view == nil ) then view = '' end
if ( view == '' ) then view = '%s' end
local i, erri = roman2int(r1, ' Erreur r2i : ')
local s = ' - ' .. r1 .. '=' .. i
if ( erri == nil ) then erri = '' end
if ( erri ~= '' ) then
s = s .. ' -> ' .. erri
end
return string.format(view, s)
-- return string.format("Hello, %s!", s)
end -- function erreurUnRomain(r1, view)
function testerDesRomains(view)
if ( view == nil ) then view = '' end
if ( view == '' ) then view = '%s' end
local s = ''
s = s .. testerUnRomain('XIJ', view)
s = s .. testerUnRomain('XIJ', view)
s = s .. testerUnRomain('MCXI', view)
s = s .. testerUnRomain('MCDXLIV', view)
s = s .. testerUnRomain('MDCLXVI', view)
s = s .. testerUnRomain('MCMXCIX', view)
s = s .. testerUnRomain('MMCCXXII', view)
s = s .. testerUnRomain('MMMMCMXCIX', view)
-- Nombres avec erreurs
s = s .. testerUnRomain('i', view)
s = s .. testerUnRomain('ERREURS', view)
s = s .. testerUnRomain('XIA', view)
s = s .. testerUnRomain('XJI', view)
s = s .. testerUnRomain('IXC', view)
s = s .. testerUnRomain('VLD', view)
s = s .. testerUnRomain('MMMMM', view)
s = s .. testerUnRomain('MMMMMYJXC', view)
s = s .. testerUnRomain('', view)
s = s .. testerUnRomain(nil)
s = s .. erreurUnRomain('ERREURS', view)
s = s .. erreurUnRomain('XIA', view)
s = s .. erreurUnRomain('XJI', view)
s = s .. erreurUnRomain('IXC', view)
s = s .. erreurUnRomain('VLD', view)
s = s .. erreurUnRomain('MMMMM', view)
s = s .. erreurUnRomain('MMMMMYJXC', view)
return s
end -- function testerDesRomains(view)
-- testerDesRomains('x') -- lance le test
-- Interface http://scribunto.wmflabs.org/
local p = {}
function p.hello()
-- {{#invoke:MathRoman.lua|hello}}
return 'Hello, world!'
end
function p.roman2integer(frame)
-- { {#invoke:MathRoman.lua|roman2integer| MMXIJ } }
local r = frame.args[1]
local i, erri = roman2int(r, ' Error r2i : ')
return i
end
function p.r2i(frame) -- shortcut of roman2integer
-- { {#invoke:MathRoman.lua|r2i| MMXIJ } }
return p.roman2integer(frame)
end
function p.integer2roman(frame)
-- { {#invoke:MathRoman.lua|integer2roman| 2012 } }
local i = frame.args[1]
local r, errr = int2roman(i, ' Error i2r : ')
return r
end
function p.i2r(frame) -- shortcut of integer2roman
-- { {#invoke:MathRoman.lua|i2r| MMXIJ } }
return p.integer2roman(frame)
end
function p.testRomans(frame)
-- { {#invoke:MathRoman.lua|testRomans|': %s<br/>'} }
local view = frame.args[1]
if ( view == nil ) then view = '' end
if ( view == '' ) then view = '%s' end
local s = testerDesRomains(view)
return s
end
function p.testText(formater, text, n)
-- { {#invoke:MathRoman.lua|testText|': %s<br/>'|Text under test. |3} }
local s = ''
local N = tonumber(n)
while ( N > 0 ) do
s = s .. string.format(formater, text)
N = N - 1
end
return s
end
return p