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 tableFromList(n: Int, a: List[Int]): scala.xml.NodeSeq = {
  def splitBy[T](a: List[T]): List[List[T]] = {
    a match {
      case Nil => Nil
      case _ => val (f, r) = a splitAt n; f::splitBy(r)
    }
  }
  def duplicate[T](t: T, n: Int): List[T] = {
    if(n <= 0) Nil else t::duplicate(t, n - 1)
  }
  <table>{splitBy(a.map{e => <td>{e}</td>}).map{e =>
    <tr>{e ++ duplicate(<td>&nbsp;</td>, n - e.length)}</tr>
  }}</table>
}

println(tableFromList(3, List(1, 2, 3, 4, 5, 6, 7)))

余った部分にパディングを行う部分のコードがイマイチ綺麗に書けてないのが不満。その辺りも含めて、もうちょっと短く書けそうな気がする。