“Lisp as an Alternative to Java”のお題を Scalaで
“Lisp as an Alternative to Java”のお題を Squeak Smalltalk で - Smalltalkのtは小文字です経由
scala勉強中に付き、上記サイトで面白い問題を発見したので早速やってみました。思ったより時間がかかったけど関数脳の良いトレーニングになった気がする。問題の詳細はリンク先をご覧下さい。
object Phone extends Application { val map = List("e","jnq","rwx","dsy","ft","am","civ","bku","lop","ghz"); val dictionary = List("an","blau","Bo\"","Boot","bo\"s","da","Fee","fern","Fest","fort", "je","jemand","mir","Mix","Mixer","Name","neu","o\"d","Ort","so","Tor","Torf","Wasser"); val phones = List("112","5624-82","4824","0721/608-4067","10/783--5","1078-913-5","381482","04824"); case class DD(word:String,digits:Seq[Int]) extends (String,Seq[Int])(word,digits) { def isDigit = word.first.isDigit override def toString = word.toString } val digiDict = dictionary.map( w => DD(w,digitsWord(w)) ) def digits(in: String): Seq[Int] = in.filter(_.isDigit).map(_.asDigit) def digitFromLetter(in: Char): Int = map.findIndexOf(_.contains(in.toLowerCase)) def digitsWord(word: String): Seq[Int] = word.map(digitFromLetter(_)).filter(_ != -1) def matchDigiDict(digits: Seq[Int]): Seq[DD]= { digiDict.filter( dd => digits.startsWith(dd.digits) ) match { case Nil => DD(digits.first.toString,digits.first::Nil)::Nil case x => x } } def patterns(digits: Seq[Int]): Seq[ Seq[DD] ] = digits.length match { case 0 => Nil::Nil case _ => matchDigiDict(digits).flatMap( dd => patterns(digits.drop(dd.digits.length)) .filter(node=> !(dd.isDigit && node.length>=1 && node.first.isDigit) ) .map(node=> dd::Nil++node)) } phones.map( p => println( p + " => " + patterns(digits(p)))) }
出力
112 => List() 5624-82 => List(List(mir, Tor), List(Mix, Tor)) 4824 => List(List(fort), List(Tor, 4), List(Torf)) 0721/608-4067 => List() 10/783--5 => List(List(je, Bo", da), List(je, bo"s, 5), List(neu, o"d, 5)) 1078-913-5 => List() 381482 => List(List(so, 1, Tor)) 04824 => List(List(0, fort), List(0, Tor, 4), List(0, Torf))