2014年3月21日金曜日

プロジェクトオイラー Problem 65 「e の近似分数」 †

Problem 65 「e の近似分数」 

2の平方根は無限連分数として書くことができる.
式.jpg
無限連分数である √2 = [1;(2)] と書くことができるが, (2) は2が無限に繰り返されることを示す. 同様に, √23 = [4;(1,3,1,8)].
平方根の部分的な連分数の数列から良い有理近似が得られることが分かる.√2の近似分数について考えよう.
式2.jpg
従って, √2の近似分数からなる数列の最初の10項は:
1, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169, 577/408, 1393/985, 3363/2378, ...
もっとも驚くべきことに, 数学的に重要な定数,
e = [2; 1,2,1, 1,4,1, 1,6,1 , ... , 1,2k,1, ...].
e の近似分数からなる数列の最初の10項は:
2, 3, 8/3, 11/4, 19/7, 87/32, 106/39, 193/71, 1264/465, 1457/536, ...
10項目の近似分数の分子の桁を合計すると1+4+5+7=17である.
e についての連分数である近似分数の100項目の分子の桁の合計を求めよ.

http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2065



解法
上から計算すると考えると難しいので分数を下から計算していくだけです。


gcd(0, B, G) :- G is abs(B).
gcd(A, B, G) :- A =\= 0, R is B mod A, gcd(R, A, G).

sum([],0):-!.
sum([X|Xs],Result):-
      !,
      sum(Xs,Re),
      Result is Re+X-48.

d(Deep,N1):-
      Deep mod 3=:=0,
      !,
      N1 is Deep//3*2.

d(_,1):-!.

calc(1,U,D):-
      !,
      U1 is U+D*2,
      D1 is D,
      gcd(U1,D1,G1),
      U2 is U1//G1,
      number_codes(U2,List2),
      sum(List2,Ans),
      write(Ans).
calc(Deep,U,D):-
      !,
      d(Deep,N),
      U1 is D*N+U,
      D1 is D,
      gcd(U1,D1,G1),
      U2 is U1//G1,
      D2 is D1//G1,
      Deep1 is Deep-1,
      calc(Deep1,D2,U2).

main65:-
      d(100,D),
      calc(99,1,D).

0 件のコメント:

コメントを投稿