4
\$\begingroup\$

I have written a MATLAB function that converts decimals into Roman numerals.

function ans = dec2rom(z)
d = [ 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
c =  {'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'};
[];
for ii = 1:numel(d)
    if z >= d(ii)    
        ans = [ans,repmat(c{ii},1,fix(z/d(ii)))];
        z = rem(z,d(ii));
    end
end
\$\endgroup\$
0

2 Answers 2

3
\$\begingroup\$

Your use of ans is very difficult to understand, it took me 5 minutes reading the lines to understand what []; really does and why it is necessary.

function r = dec2rom(z)
d = [ 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
c =  {'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'};
r='';
for ii = 1:numel(d)
    if z >= d(ii)    
        r = [r,repmat(c{ii},1,fix(z/d(ii)))];
        z = rem(z,d(ii));
    end
end

/second version following the discussion to the other answer:

function r = dec2rom(z)

t={ 1000, 900, 500,  400, 100,   90,  50,   40,  10,    9,   5,    4,   1;
    'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'};
r='';
for ii = t
    num = ii{1};
    symb = ii{2};
    r = [r,repmat(symb,1,fix(z/num))];
    z = rem(z,num);
end

Now having the chars and numbers aligned in a data structure and using a simplified for loop.

\$\endgroup\$
2
\$\begingroup\$

I fully agree with what Daniel said.

A few notes:

  • actually you can get rid of the if inside the for loop. (then you just have a repmat(,,0) - but it makes things easier to read and often gives a little speed bump.

  • it would be a good idea to check the input number is >0 and maybe have a warning for rational z.

  • typically I prefer related numbers to be stored together - it makes things way easier to read and debug.

think something like

romlist = {{1000,'M'}, {500,'D'},...}

This allows for the index to completely disapper, and you don't need to worry about indexes at all.

for i=romlist
    num = i{1}{1}
    symb = i{1}{2}
end
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Do not use nested cell arrays to store matrix shaped data, a cell matrix is better: romlist={1000,500;'M','D'},for ii=romlist,num = ii{1},symb = ii{2},end \$\endgroup\$
    – Daniel
    Commented Mar 7, 2016 at 13:48
  • 1
    \$\begingroup\$ I was thinking about that. My main point is to keep the symbol and value together. In the matrix this is again lost. My first idea was a vector of struct - but that was way to complicated for such a simple idea. Although having a matrix and then transpose it would work. \$\endgroup\$
    – bdecaf
    Commented Mar 7, 2016 at 13:58
  • \$\begingroup\$ Or format the matrix in a clean way, aligning first and second row. \$\endgroup\$
    – Daniel
    Commented Mar 7, 2016 at 14:00
  • \$\begingroup\$ That's true. But personally I like my lines to be less then 70 characters wide and therefore try to avoid this arrangement. Also adding and deletion of entries becomes imho more of a hassle. \$\endgroup\$
    – bdecaf
    Commented Mar 7, 2016 at 14:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.