数列圧縮変形版
2008-09-26で提案されている変形版をsumimさんがSqueakを使って華麗に解いていたので、Scalaでマネしてみた。
abstract class Compact { def ::(l: Compact): Compact =CompactList(l,this) def ::(l: Int): Compact } case class CompactList(car: Compact, cdr: Compact) extends Compact { def ::(l: Int) = (l::car)::cdr override def toString = car+" , "+cdr } case class Interval(s:Int, e:Int, step:Int) extends Compact{ def ::(l: Int): Compact = if(l==s-step) Interval(l,e,step) else notMatch(l) def notMatch(l: Int) = N(l)::this } case class Pair(e1: Int, e2: Int) extends Interval(e1,e2,e2-e1) { override def notMatch(l: Int) = Pair(l,s)::N(e) override def toString = e1+" , "+e2 } case class N(n: Int) extends Interval(n,n,0) { override def ::(l: Int): Compact = Pair(l,n) override def toString = n.toString } object N extends N(0) { override def ::(l: Int): Compact = N(l) }
Scheme どう書く?的をScalaで書いてみた
Scheme どう書く?的 - higepon blogより
整列済みの number のリストがある。
'(1 3 4 5 6 12 13 15)
このようなリストで数が連続している部分は '(1 2 3) -> '(1 . 3) のように両端のみを書くような記法を導入する。
最初の例のリストであれば以下のようになる。
'(1 (3 . 6) (12 . 13) 15)
このようなリストの変換をするコードを書きたい。
ソース
case class R(s: Int,e: Int) case class N(n: Int) extends R(n,n) def f( input: List[R] ): List[R] = input match { case R(c1,c2)::N(c3)::cdr if(c2+1==c3) => f(R(c1,c3)::cdr) case car::cdr => car::f(cdr) case r => r } println(f((1::3::4::5::6::12::13::15::Nil)map(N(_))))
実行結果
List(N(1), R(3,6), R(12,13), N(15))
クラスと関数型の出会いに万歳!
GNU Screenを複数人で共有する
GNU screenには複数のターミナルから1つのセッションを共有する機能が付いている。これを使えば作業内容の確認や指導、共同作業が遠隔地から行えるようになる。
1. Aさん: screen -S <名前>でセッションに名前を付けて起動
2. Aさん: C-a :multiuser onで外部からの接続を許可
3. Bさん: screen -lsで接続可能なセッションリストを表示
4. Bさん: screen -x <名前>で接続
“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))
scalaでテーブル出力
scala-user MLに投稿されていた問題で、
入力: 1, 2, 3, 4, 5, 6, 7 のようなリスト
出力:<table> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>4</td> <td>5</td> <td>6</td> </tr> <tr> <td>7</td> <td> </td> <td> </td> </tr> </table>となるようなプログラムを作成せよというもの(出力はNodeSeqなので出力を整形するのは不要)。
こんな問題が出ていたので、練習がてら作ってみたお。
def table(n: Int, list: List[Int]): NodeSeq = { def tr(l: List[Int]): NodeSeq = l match { case Nil => Nil case _ => val (c,r) = l.splitAt(n) <tr>{c.map(e => <td>{e}</td>)++ {range(c.length,n).map(_ => <td>&nbsp;</td>)}}</tr> ++ tr(r) } <table>{tr(list)}</table> } println(table(3,List(1,2,3,4,5,6,7)))
Scalaはまだまだ知らんことが沢山あるので、もっと良いやり方があると思うけど。
screenのウィンドウに名前を付ける
ウィンドウが増えてくるといちいち一つずつ切り替えて行くのも大変だ。
そこで、各ウィンドウに名前を付けてそこにダイレクトで飛べると便利だ。
.screenrc
caption always "%{= wk} %-w%{=bu dr}%n %t%{-}%+w %= %{=b wb}%y/%m/%d(%D) %{=b wb}%c"
ステータスバーにウィンドウ名と番号がタブのように並ぶ。
C-a A
そのウィンドウに名前を付ける