Alien Numbers - how Scala-ish is my solution? I'm trying to solve an old GCJ. It's a very simple puzzle, but I'm trying to sharpen my Scala-fu.

Basically, you're getting a list of triple number srcLanguage dstLanguage, where number is an integer given in the numeral system of srcLanguage. You should translate it to the numeral system of dstLanguage.

A numeral system is simply a string of all possible digits, in ascending order. The decimal numeral system is represented by 0123456789, the binary numeral system is 01, and the hexadecimal one 0123456789ABCDEF.

For example:


3 0123456789 01 -&gt; 11
3 0123       AB -&gt; BB



Here's how I implemented it in Scala:

case class Langs(num:String,srcLang:String,dstLang:String)
object Langs {def fromLine(line:String):Langs = {
    val ar = line.split(" ");return Langs(ar(0),ar(1),ar(2))}}
object Translate {
  def lang2int(lang:String,num:String):Long = {
    var b = BigDecimal(0)
    val dmap = (lang.toList.zipWithIndex).toMap
    val digitsList = num map dmap
    val valueList = digitsList.reverse.zipWithIndex map (
        x =&gt; x._1 -&gt; math.pow(dmap.size,x._2))
    return valueList.map(x=&gt;x._1*x._2).sum.toLong
  }
  def int2lang(lang:String,_num:Long):String = {
    var num = _num
    val dmap = (lang zip (0.toLong to lang.size)).map(_.swap).toMap
    val sb = StringBuilder.newBuilder
    while (num &gt; 0) {
        sb.append(dmap(num % dmap.size))
        num = num/dmap.size
    }
    sb.reverse.toString
  } 
  def lang2lang(l:Langs):String = int2lang(l.dstLang,lang2int(l.srcLang,l.num))
}

object mymain {
  def main(args : Array[String]) : Unit = {
    val s = "A-large-practice"
    val basef = new java.io.FileInputStream("~/Downloads/"+s+".in")
    val f = new java.util.Scanner(basef)
    val out = new java.io.FileWriter(s+".out")
    val n = f.nextInt
    f.nextLine
    for (i &lt;- 1 to n) {
      val nl = f.nextLine
      val l = Langs.fromLine(nl)
      out.write("Case #"+i+": "+Translate.lang2lang(l)+"\n")
    }
    out.close
  }
}
You should definitely use scala.io.Source for File-IO
I wouldn't consider String splitting a responsibility of a general-purpose class. This should be done in the main loop
For tuples you can write map{ case (one,two) => ... }, which is often clearer than using x._1 and x._2
You don't need to write return if it's the last statement of the block
You can use pattern matching when defining vals: val Array(x, y, z) = line.split(" ") 


Here is my attempt:

case class Langs(num:String, srcLang:String, dstLang:String)

object Langs {
  def fromLine(line:String):Langs = {
    val Array(num, srcLang, dstLang) = line.split(" ")
    Langs(num, srcLang, dstLang)
  }
}

object Translate {
  def lang2int(lang:String,num:String):Long = {
    val dmap = lang.toList.zipWithIndex.toMap
    val digitsList = num map dmap
    val valueList = digitsList.reverse.zipWithIndex map {
      case (one, two) =&gt; one -&gt; math.pow(dmap.size, two)}
    valueList.map{case (one,two) =&gt; one*two}.sum.toLong
  }

  def int2lang(lang:String, num:Long):String = {
    val dmap = (0.toLong to lang.size zip lang).toMap
    Iterator.iterate(num)( _/dmap.size).takeWhile(_ &gt; 0).map(n =&gt; 
      dmap(n % dmap.size)).mkString.reverse
  } 

  def lang2lang(l:Langs):String = int2lang(l.dstLang,lang2int(l.srcLang,l.num))
}


Eliminating the while loop isn't that straight-forward, maybe someone else has an idea how to avoid that Iterator train-wreck.

[Edit]

I asked in another forum for a better solution for int2lang, and got this answer:

def int2lang(lang: String, num: Long): String = {
  val dmap = (0L to lang.size) zip lang toMap
  val size = dmap.size
  def loop(num: Long, l: List[Char]): List[Char] =
    if (num == 0) l else loop(num/size, dmap(num%size) :: l)
  loop(num, Nil).mkString
}


The nice thing about this is that the reverse is gone.