# toroman

function toroman( num [, mode] ) --> roman

## Description

Converts the number num to a roman string. The number value must be positive.

## Parameters

num

A number that should be convert.

mode

A number that specifies the type roman number that should be returned.

• 0 for a classic roman number, this is also the default variant.

• 1/2/3 for a more concise variants, check the examples to see the difference.

• 4 for a simplified roman number.

## Return Values

roman

A roman number as string.

## Code

--ZFUNC-toroman-v1
local function toroman( num, mode ) --> roman
mode = mode or 0
if num < 1 or num > 3999 then return "" end

local chars = { "M", "D", "C", "L", "X", "V", "I" }
local vals = { 1000, 500, 100,  50,  10,   5,   1 }
local sidx =  {   3,   3,   5,   5,   7,   7 }
local last = #vals

local roman = {}
while num > 0 do
local i = 1
while i <= last do
local v = vals[ i ]
if num >= v then
num = num - v
table.insert( roman, chars[ i ] )
i = last + 1
else
local j = math.min( sidx[ i ] + mode, last )
local n = sidx[ i ]
while j >= n do
local v2 = v - vals[ j ]
if num >= v2 then
num = num - v2
table.insert( roman, chars[ j ] )
table.insert( roman, chars[ i ] )
i = last + 1
j = 1
else
j = j - 1
end
end

i = i + 1
end
end
end

return table.concat( roman )
end

## Examples

local t = require( "tapered" )
local toroman = require( "toroman" )

t.is( "III", toroman( 3 ) )
t.is( "VII", toroman( 7 ) )
t.is( "MCMXCIX", toroman( 1999 ) )

t.is( "CDXCIX", toroman( 499, 0 ) )
t.is( "LDVLIV", toroman( 499, 1 ) )
t.is( "XDIX", toroman( 499, 2 ) )
t.is( "VDIV", toroman( 499, 3 ) )
t.is( "ID", toroman( 499, 4 ) )

t.is( "", toroman( -1 ) )

-- should allow only 3999 as max value
t.is( "MMMCMXCIX", toroman( 3999 ) )
t.is( "", toroman( 4000 ) )

t.done()