Challenged by Sandy Metz's newsletter, I've tried to implement this kata from exercism. However, my solution, which passes the tests, is quite a lot simpler than Sandy's solution. Ok, so she's using refinements and also supports the inverse, but still... As she's probably smarter than me, do I miss something?
class Fixnum
ROMAN = {
1000 => "M",
900 => "CM",
500 => "D",
400 => "CD",
100 => "C",
90 => "XC",
50 => "L",
40 => "XL",
10 => "X",
9 => "IX",
5 => "V",
4 => "IV",
1 => "I"
}
def to_roman
result = ""
ROMAN.reduce(self) { |number, (divider, letter)|
letter_multiplier, remainder = number.divmod(divider)
result << (letter * letter_multiplier)
remainder
}
result
end
end
reduce
isn't idiomatic. The "initial" value you pass in should be the thing you are building up, in this case the roman string. the problems is you also have a temporary variable -- the "number". better to define that outside ofreduce
, so you can let thereduce
expression be the return value. \$\endgroup\$reduce
has a side effect, which is not nice. \$\endgroup\$