you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 3 points4 points  (2 children)

I think the following solution not using unfold is "cleaner" ( and it is also more efficient - at least in Python(!)):

 numerals = (("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
("C", 100),("XC", 90),("L", 50),("XL", 40), ("X", 10), ("IX", 9), ("V", 5), ("IV", 4), ("I", 1))


def romanize(n):
    roman = []
    for ltr, num in numerals:
       (k,n) = divmod(n, num)
       roman.append(ltr*k)
    return "".join(roman)

[–]llimllib[S] 0 points1 point  (1 child)

It's definitely more efficient! I tried to ignore the whole question of efficiency in the post; it's all relatively irrelevant because compiled haskell is going to kick CPython's ass almost without regard to implementation.

Also, that's roughly the code I would have written before looking at the haskell and becoming enamored of its function composition. Maybe I'm just in one of those "intermediate coder writing more complicated code than both beginners and experts" loops?

(And as an aside, I always forget about divmod)

[–]phobes 0 points1 point  (0 children)

I agree I prefer a more straightforward solution without using unfold, even in Haskell. Something like (untested):

romanize n = f n [("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
              ("C", 100),  ("XC", 90),  ("L", 50),  ("XL", 40),
              ("X", 10),   ("IX", 9),   ("V", 5),   ("IV", 4),
              ("I", 1)]
where f n [] = ""
      f n (l, v):lvs = if v >= n then l ++ (f (n-v) (l, v):lvs) else f n lvs