I have a couple of things I wanted to review, and decided to do it using a simple algorithm which most
people will understand.
Roman numerals are as follows: I, II, III, IV, V, VI, VII, VIII, IX, X
XI, XII, XIII, XIV, XV, XI, XII, XIII, XIX, XX, XXI….
Wikipedia can tell you how they work. But how could you do this in Scala, and what Scala features could be illustrated as we try out various ways?
The following examples are not the best way to do it, but they all work, and to prove it here is the unit test
Java Imperative style
The code below is obviously very long winded, but it shows how it could be done, without much thought, in a (bad) Java style implementation, but in Scala. It should be faily obvious how it works
Don’t do it that way, but it is a way…
I again hacked out a fold left solution, not because it is a good way to do it - the good ways come later, but because I was interested. Sadly, as an experiment it failed - it does work, but its mutable and ugly and the real version comes later. This version is included as part of the journey towards the final implementations which come later.
It does illustrate Scala type, Tuples and their access, and also uses a Tuple2 as an accumulator for the foldLeft.
Things of interest here, are initialisation of a Tuple by simply writing (“”, value). Using a type for Tuple4 and so on.
The boring way again
Going back to the traditional way to approach this, and keep it readable, perhaps we could have a
similar approach to the imperative style, but with no mutable state.
Strings in Scala have some features, such as “M”*3 = “MMM”. Also, you can add expressions together to create the output string.
So, playing with these features, and removing var’s we could still have a longhand version as below:
Less code, it’s Scala
Scala should not need nearly as many lines as above, niether should Java come to that, so lets try and be at least a little cleverer
I again use “M”*3=”MMM” at the start, and now I also start to use a List of values, and index into the List based on 100’s, 10’s and 1’s.
I admit I did not think about this until I finally googled how other people implement the convert in Scala, and I came upon the following rather lovely implementation.
I take no credit for it and hope the author is happy for me to show it below.
Fold Left again
It would not be right to leave the bad foldLeft done previously as the only example, so here it is again.
A tuple2 as the accumulator again, and the trick which means no special handling for 9, 5 or 4.
Expressive or incomprehensible?
Some people like to make Scala short at the expense of the poor devs who come after them. So, here is an obfuscated version
Here we see a Tuple2 being created with a syntax of 1000->”M”, as an alternative to (1000,”M”).
A final Tuple10
During my experimentation I came up with a Tuple10 solution which I think is easier to understand. Reading code for something like this should not require much thought. Note I am not scoring any of these for speed, memory or anything else, I’m just showing some different ways of doing it in Scala, and it is the number of different ways which I find interesting.
I just can’t stop
The Tuple10 could become the class below, it seems there is no end to the ways we can do this. Why make the changes, well, Arrays are mutable, so we use Lists in preference, and to access the nth element of a List is shorter to type than to access the nth element of a Tuple10.
Hopefully, if you are getting into Scala, you can see many different approaches above, some are flawed, some are lengthy and maybe a couple are desirable. The aim of this post was to do it as many ways as I could think of. I can think of more, but will stop.