Problem45

30分プログラム、その319。Problem45 - Project Euler

三角数, 五角数, 六角数は以下のように生成される.

三角数Tn=n(n+1)/2 1, 3, 6, 10, 15, ...
五角数Pn=n(3n-1)/2 1, 5, 12, 22, 35, ...
六角数Hn=n(2n-1) 1, 6, 15, 28, 45, ...

T285 = P165 = H143 = 40755であることが分かる.
次の三角数かつ五角数かつ六角数な数を求めよ.

id:banjunのコードから学んだことだけれども、解の公式的なものを使うことである数Nが三角数かどうかの判断ができる。
そこで、六角数を順に見ていき、最初の三角数かつ五角数を探すようにした。六角数にしたのは、数の増加が速いほうが、答えに到達するのも速い気がしたので。

使い方

1> c("problem45.erl").
{ok,problem45}
2> problem45:loop(2).
T(143)=40755
2> problem45:loop(144).
T(27693)=1533776805
ok

ソースコード

-module(problem45).
-compile([export_all]).

t(N)->
    N*(N+1) div 2.
p(N)->
    N*(3*N-1) div 2.
h(N)->
    N*(2*N-1).


is_rem(X,Y)->
    X == trunc(X) andalso 
	trunc(X) rem Y =:= 0.

is_t(T)->
    D = -1+math:sqrt(1+8*T),
    is_rem(D,2).

is_p(P)->
    D = 1+math:sqrt(1+24*P),
    is_rem(D,6).

is_h(H)->
    D = 1+math:sqrt(1+8*H),
    is_rem(D,2).


is_satisfy(N)->
    is_t(N) andalso is_p(N).

loop(N)->
    H = h(N),
    case is_satisfy(H) of
	true -> 
	    io:format("T(~p)=~p~n",[N,H]);
	_ -> 
	    loop(N+1)
    end.