Oops I did it again. Last Friday I participated again in Olimex’s weekend programming challenge. It was the 30th. This time we had to come up with a numbers converter, which should convert arabic to roman numbers. For example: providing 34 should result in the output XXXIV. My current hammer is Meteor, so I made a little client-side-only Meteor app that does the trick. You can see it in action here.
My initially imagined solution worked out straight, so I finished in less than an hour on Friday night. In retrospection, the hardest part was constraining the input to valid numbers. I haven’t done this before, but will need this soon in another project. Which made the hastle worthwhile, I guess. At first here is the template code. Actually nothing fancy here.[gist https://gist.github.com/Crenshinibon/7223037]
The following gist shows the logic:[gist https://gist.github.com/Crenshinibon/7223065]
I have an array of arrays that hold the roman symbols. Every sub-array represents the two valid symbols for each decimal place. One below 5 and one for 5 and above. In roman there is a different symbol for every 5 steps.
The function updateRoman does the actual conversion. I step through the provided number, represented as a string, from left to right using the strings length as the offset for the roman symbols array. The switch statement handles the different cases. Special are 4 and 9, in those cases the ‘next’ symbol is used and instead of the usual addition, a subtraction is used by placing the lower symbol on the right side of the ‘next’ one. For example IV for four instead of IIII.
As a result I set a session variable that stores the roman representation. The session variable gets read in the Template.main.roman helper, which in turn gets called from the template. Since session variables are reactive, the UI reflects automagically the new value.
The keydown handler is responsible for letting only valid characters (0-9) through. At first I check if the key code of the pressed key doesn’t represent a control key (the arrow keys for example). If it’s not a control key the default behaviour (e.g. putting the value in the textfield) gets suppressed.
Next I check if the pressed key represents a digit. If the string is empty zero is not allowed otherwise all digits get through. I append the character representing the current key to the textfield and trigger the conversion function.