数列圧縮変形版

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)
}
実行結果
  >println(1::4::6::8::9::10::11::12::15::N)
  1 , 4 , 6 , Interval(8,12,1) , 15

Squeak版と違って既存クラスをうまく使えてないねー><。Implicit Conversionとか使えばうまくいくのかなー。
さすが動的言語は拡張性が高いねぇ。

あと::演算子が左結合なせいでSqueak版と違う答えが返ってくる。何通りか答えあるのね。

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でテーブル出力

リストから表を生成する - kmizuの日記より

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>&nbsp;</td>
    <td>&nbsp;</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>&amp;nbsp;</td>)}}</tr> ++ tr(r)
    }
    <table>{tr(list)}</table>
  }
  println(table(3,List(1,2,3,4,5,6,7)))

Scalaはまだまだ知らんことが沢山あるので、もっと良いやり方があると思うけど。

MACの画面キャプチャ

Command + shift + 3

全画面キャプチャ(ファイル)

Command + shift + 4

一部キャプチャ(ファイル)

Ctrl + Command + Shift + 3

全画面キャプチャ(クリップボード)

Ctrl + Command + Shift + 4

一部キャプチャ(クリップボード)

screenのウィンドウに名前を付ける

ウィンドウが増えてくるといちいち一つずつ切り替えて行くのも大変だ。
そこで、各ウィンドウに名前を付けてそこにダイレクトで飛べると便利だ。


.screenrc

caption always "%{= wk} %-w%{=bu dr}%n %t%{-}%+w %= %{=b wb}%y/%m/%d(%D) %{=b wb}%c"
ステータスバーにウィンドウ名と番号がタブのように並ぶ。

C-a A

そのウィンドウに名前を付ける

C-a [0-9]

指定したウィンドウ番号へ飛ぶ

参考:http://q.hatena.ne.jp/1134693287