Module:MathRoman.lua

From eCatalog Manager Wiki
Jump to navigation Jump to search
--[[ 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, vue) 
   if ( r1 == nil ) then r1 =  end
   local i, erri = roman2int(r1, ' Erreur r2i : ')
   local rm, errm = int2roman(i, ' Erreur i2r : ')
   print( r1..'='..i..'='..rm )
   if ( ( erri == nil ) or ( erri ==  ) ) then erri =  end
   if ( ( errm == nil ) or ( errm ==  ) ) then errm =  end
   if ( ( erri ~=  ) or ( errm ~=  ) ) then print( ' -> '..erri..errm ) end
 end -- function testerUnRomain(r1, vue)
 function erreurUnRomain(r1, vue)
   if ( r1 == nil ) then r1 =  end
   local i, erri = roman2int(r1, ' Erreur r2i : ')
   print( ' - '..r1..'='..i )
   if ( ( erri == nil ) or ( erri ==  ) ) then erri =  end
   if ( erri ~=  ) then print( ' -> '..erri..erri ) end
 end -- function erreurUnRomain(r1, vue)
 function testerDesRomains(vue)
   testerUnRomain('XIJ', vue)
   testerUnRomain('MCXI', vue)
   testerUnRomain('MCDXLIV', vue)
   testerUnRomain('MDCLXVI', vue)
   testerUnRomain('MCMXCIX', vue)
   testerUnRomain('MMCCXXII', vue)
   testerUnRomain('MMMMCMXCIX', vue)
   -- Nombres avec erreurs
   testerUnRomain('i', vue)
   testerUnRomain('ERREURS', vue)
   testerUnRomain('XIA', vue)
   testerUnRomain('XJI', vue)
   testerUnRomain('IXC', vue)
   testerUnRomain('VLD', vue)
   testerUnRomain('MMMMM', vue)
   testerUnRomain('MMMMMYJXC', vue)
   testerUnRomain(, vue)
   testerUnRomain(nil)
   erreurUnRomain('ERREURS', vue)
   erreurUnRomain('XIA', vue)
   erreurUnRomain('XJI', vue)
   erreurUnRomain('IXC', vue)
   erreurUnRomain('VLD', vue)
   erreurUnRomain('MMMMM', vue)
   erreurUnRomain('MMMMMYJXC', vue)
 end -- function testerDesRomains(vue) 
 testerDesRomains('x') -- lance le test
-- http://www.mediawiki.org/wiki/Extension:Scribunto/Parser_interface_design
-- Proposed interface summary
-- 
-- Script error: No such module "module_name".
-- 20120505 18:37
function p.function_name( frame )
       -- Get arg1
       local arg1 = frame.args[1]
        -- Get name1
       local name1 = frame.args.name1
        -- Get name1 by preprocessing
       name1 = frame:preprocess( '{{{name1}}}' )
        -- Put all arguments into a real table
       local t = {}
       for name, value in frame:argumentPairs() do
               t[name] = value
       end
        -- Make a <ref> tag
       local s = frame:preprocess( '<ref>Note</ref>' )
        -- Call a template
       s = s .. frame:expandTemplate{ title = 'tpl', args = {foo = arg1} }
        -- Return expanded text
       return s
end
-- return p
-- 20120505 19:50
function r.roman2integer( frame )
       -- Get arg1 arg2
       local r1 = frame.args[1]
       local err = frame.args[2]
       -- internal process
       if ( r1 == nil ) then r1 =  end
       local i, erri = roman2int(r1, ' Error : ')
       s = i
       if ( ( erri == nil ) or ( erri ==  ) ) then erri =  end
       if ( erri ~=  ) then s = s .. erri end
        -- Return expanded text
       return s
end
return r