LifeGameに2次元配列はいらない

LifeGame

生きているセルだけを考えていればLifeGameは作れる。そうなるとListとタプルがあれば、2次元配列はいらない事に気づいたのでやってみた。

class Life(var l: List[(Int, Int)]) {
  def next() {
    l = step(l);
  }
  
  def step(l: List[(Int, Int)]): List[(Int, Int)] = {
    val m = countLife(l.flatMap(LifeAround).sort(tSort)).sort(mSort);
    nextLife(m, l).sort(tSort);
  }
  
  def countLife(l: List[(Int, Int)]): List[((Int, Int), Int)] = {
    def c(h: (Int, Int), i: Int, l: List[(Int, Int)]): List[((Int, Int), Int)] = {
      l match {
        case x :: xs => if (h == x) c(x, i + 1, xs) else (h, i) :: c(x, 1, xs);
        case _ => List((h, i));
      }
    }
    l match {
      case x :: xs => c(x, 1, xs);
      case _ => List[((Int, Int), Int)]();
    }
  }
  
  def LifeAround(t: (Int, Int)): List[(Int, Int)] = {
    val x = t._1;
    val y = t._2;
    List((x - 1, y - 1), (x - 1, y), (x - 1, y + 1), (x, y - 1), (x, y), (x, y + 1), (x + 1, y - 1), (x + 1, y), (x + 1, y + 1))
  }
  
  def tSort(s: (Int, Int), n: (Int, Int)): Boolean = {
    if (s._1 < n._1)
      true
    else if (s._1 == n._1)
      if (s._2 < n._2)
        true
      else if (s._2 == n._2)
        true
      else false
    else false
  }
  
  def mSort(s: ((Int, Int), Int), n: ((Int, Int), Int)): Boolean = {
    tSort(s._1, n._1);
  }
  
  def nextLife(m: List[((Int, Int), Int)], l: List[(Int, Int)]): List[(Int, Int)] = {
    if (m.isEmpty) List()
    else if (l.isEmpty == false && m.head._1 == l.head) {
      if (m.head._2 == 3 || m.head._2 == 4) {
        l.head :: nextLife(m.tail, l.tail);
      } else {
        nextLife(m.tail, l.tail);
      }
    } else {
      if (m.head._2 == 3)
        m.head._1 :: nextLife(m.tail, l)
      else
        nextLife(m.tail, l);
    }
  }
  
  override def toString() = {
    l = l.sort(tSort);
    val xMin = l.foldLeft(1)((z, x) => if (z < x._1) z else x._1) - 1;
    val yMin = l.foldLeft(1)((z, x) => if (z < x._2) z else x._2) - 1;
    val xMax = l.foldLeft(1)((z, x) => if (z < x._1) x._1 else z) + 1;
    val yMax = l.foldLeft(1)((z, x) => if (z < x._2) x._2 else z) + 1;
    def f(p: (Int, Int), l: List[(Int, Int)]): String = {
      l match {
        case x :: xs =>
          (if (p._1 < x._1) {
            " . " * (yMax - p._2) + "\n" + ((" . " * (yMax-yMin+1)) + "\n") * (x._1 - p._1 - 1) + " . " * (x._2 - yMin)
          } else " . " * (x._2 - p._2 - 1)) + " * " + f(x, xs);
        case _ => " . " * (yMax - p._2) + "\n . " + ((" . " * (yMax - yMin)) + "\n")
      }
    }
    l match {
      case x :: xs => " . " + f((xMin, yMin), l);
      case _ => " . ";
    }
  }
}
object Lifegame {
  def main() {
    var l = List((1, 2), (2, 3), (3, 1), (3, 2), (3, 3));
    val lifegame = new Life(l);
    println(lifegame);
    for (i <- 1 to 10) {
      lifegame.next();
      println(lifegame);
    }
  }
}

改めて見るとコードが汚い