CodeIQ:三角形は何通り?

私自身が表題の問題を解いた時のプログラムについて解説します。
問題の詳細は「三角形は何通り?」(CodeIQ)を参照してください。

問題の概要

問題を引用します。
【問題】
入力nに対して
1≦a≦b≦c≦n(a, b, c, nはすべて整数)を満たすa, b, cの中で、
これらを3辺とする三角形が成り立つ場合の組み合わせを求めるプログラムを書いてください。

【入力】
標準入力から、整数n(1≦n≦1000000)が与えられます。

【出力】
標準出力に、条件を満たす組み合わせの総数のみを出力してください。

【ヒント】
三角形が成り立つ条件は、(一番長い辺の長さ)<(残り2辺の長さの和)と考えることができます。
具体的には、(a, b, c) = (1, 2, 3)の場合は1 + 2 = 3なので三角形を作ることができませんが、(1, 2, 2)の場合は1 + 2 > 2なので三角形を作ることができます。

たとえばn = 3とすると、(a, b, c)のすべての組み合わせは、
(1, 1, 1)
(1, 2, 2)
(1, 3, 3)
(2, 2, 2)
(2, 2, 3)
(2, 3, 3)
(3, 3, 3)

の7通りになりますので、7と出力します。

【入出力サンプル】
Input
3

Output
7

私のプログラム

Rubyで解答しています。

#!/usr/bin/ruby

# main OEIS A002623
while line = gets
	line.strip!
	if line.empty? then next end

	n = line.to_i - 1
	p (n+2)*(n+4)*(2*n+3)/24
end

解説

多分、自力で考えると難しい(数学能力が要求される)です。
この問題の答えはOEISで調べれば必ず発見できると予想し、私は早々に自力で考えるのを諦めました。

やったこと

まず単純に全パターン総当たりで三角形を作れるかどうかを調べるプログラムを書きました。何も考えず3重ループで列挙し短い2辺の和がもっとも長い辺よりも大きくなるかどうかをチェックするだけです。
その数列をOEISで検索し、その中で最も簡単だった式を使いました。

solve()

OEISで見つけた数式は次の通りです。
a(n)=floor((n+2)*(n+4)*(2*n+3)/24)
Rubyでは整数同士の割り算は商だけになるのでわざわざfloor()で小数点以下を捨てる必要がなくプログラムの通りになります。

雑感

多分、動的計画法でパターンを作ってもできると思います。