Showing posts with label sample. Show all posts
Showing posts with label sample. Show all posts

Monday, January 14, 2008

Roman numerals in Scala

I just read about converting Ints to Romans numerals in Python and Haskell and thought... gee... I can do that in Scala:


def romanize(number: Int) = {
val numerals = List(("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))

def next(in: Int) = numerals.filter(_._2 <= in) match {
case (s, v) :: _ => Some((s, in - v))
case _ => None
}

unfold(number)(next).mkString("")
}

def unfold[T, R](init: T)(f: T => Option[(R, T)]): List[R] = f(init) match {
case None => Nil
case Some(r, v) => r :: unfold(v)(f)
}



The 'unfold' function is not part of the standard Scala distribution, but looks to be darned useful. It takes an initial value and a function that returns the "next" thing and unrolls the initial value into a List. Nifty.

The actual "romanize" function contains a local definition of the roman numerals and the "next" function which finds the next match in the list of roman numerals. This function, along with the initial value are passed into unfold which returns a List of Roman numerals. mkString turns the list in a single String.

Short, sweet, and to my eye, the Scala and Haskell versions are very similar in complexity.