- Roman Numerals Kata
- Things that I applied or learnt along the journey that led to the final solution -
- Approach the problem in small steps. I was solving this kata for the first time, I didn't know of any pattern whatsoever initially,
hence took this problem, one step at a time and it eventually helped me get to solution. Often times one worries about the end solution or just the destination, without traveling the journey bit by bit.
- I know you may think this approach(solving for one test at a time as done in this commit and this one) wouldn't give you the desired solution that'll satisfy all cases, but trust me it will help you eventually get there. That's why this approach is worth it.
- Used the older hash syntax in ruby so that I could leverage keys as strings. With this I could do away with the
to_s
that I was using here. - Learnt that I don’t have to use a more higher order class like the
Numeric
class. Instead, I could useFixnum
. I also learnt about the hierarchy of these classes.Numeric
is the parent ofInteger
which in turn is the parent ofFixnum
. - Learnt that
reverse_each
is much faster than usingreverse.each
and made the relevant refactoring here - Refactoring related learnings
* When I was looking at other people's solution like that of rwz's, I realized I can define my
ROMAN_NUMERALS
related hash in the reverse order like what was done here and thereby I wouldn't even need to use thereverse_each
method, saving me an additional computation. * I learnt that I could further simplify my solution after referring to rwz's solution. Theif...else
related branches that I had introduced to handle the subtractive notation related to roman numerals can be dealt without using that amount of branching. I made the relevant changes wrt this learning in this commit. * Learnt how we could useeach_with_object
to do away with a temp variable from henrik's solution. Appropriate change was made in this commit. Below is how the code looks before and after usingeach_with_object
Before
def to_roman
num = ''
number_to_convert = self
ROMAN_NUMERALS.each do |roman_numeral, numeric_equivalent|
next if numeric_equivalent > number_to_convert
quotient, remainder = number_to_convert.divmod(numeric_equivalent)
number_to_convert = remainder
num << roman_numeral * quotient
end
num
end
After
def to_roman
number_to_convert = self
ROMAN_NUMERALS.each_with_object("") do |(roman_numeral, numeric_equivalent), roman_equivalent|
next if numeric_equivalent > number_to_convert
quotient, remainder = number_to_convert.divmod(numeric_equivalent)
number_to_convert = remainder
roman_equivalent << roman_numeral * quotient
end
end
- I'd like to leave you with one last thought wrt solving this kata. Jim Weirich when solving this kata at RubyConfIndia 2013 said(start listening from
7:52
onwards),
I don't want to write code for special cases until I understand the general case first.
For me, this was something I wasn't doing very consciously all this while but I felt, it's definitely something worth reflecting upon and further experimenting with.
- Wrapping up, I would like to thank Jim for the above thought and for his work that has helped so many people. Also, my learnings here wouldn't have been possible without those who've contributed to exercism and to those whose solution I had an opportunity to refer to. I'm thankful to them as well.