プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問をやる。今回は、Q20:受難のファサードの魔法陣。

1 14 14 4
11 7 6 9
8 10 10 5
13 2 3 15

Q: 上の魔法陣を使い、以下の条件で足し算をした結果、その和が同じになる組み合わせが最もおおくなる値(和)を求める。

  • 足し合わせるのは、縦・横・斜めに限らない
  • 足し合わせる数字の個数は4つに限らない
(1 to numbers.length).foldLeft(Map.empty[Int,Int]){(y,num) =>
  numbers.zipWithIndex.combinations(num).foldLeft(y){(z,n) =>
    val v = n.foldLeft(0){(x,s) => x+s._1}
    z.updated(v,z.getOrElse(v,0)+1)
  }
}.maxBy(_._2)

Scalaのcombinationsは、Rubyのcombinationと異なり、同じ値を区別しないので、zipWithIndexを使って区別するようにしている。すごい無駄感。 区別しなかったとしても、66になるしね。。