Code: Alles auswählen
romanize = concat . unfoldr next
where next 0 = Nothing
next x = Just $ second (x-) $ head $ filter ((<=x) . snd) numerals
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)]
Code: Alles auswählen
def romanize(n):
result = []
for r, v in (('M', 1000), ...):
while n >= v:
n -= v
result.append(r)
return "".join(result)
Code: Alles auswählen
def romanize(n):
def next(n):
for r, v in numerals:
while n >= v:
n -= v
yield r
return "".join(next(n))
Code: Alles auswählen
def ifold(f, x):
while True:
r, x = f(x).next()
yield r
def romanize(n):
def next(n):
for r, v in numerals:
if n >= v:
yield r, n - v
return "".join(ifold(next, n))
Würde itertools bereits ifold enthalten, wäre diese Lösung sogar recht kurz:
Code: Alles auswählen
def romanize(n):
def next(n): return ((r, n - v) for r, v in numerals if n >= v)
return "".join(ifold(next, n))
Stefan