2014年3月15日土曜日

プロジェクトオイラー Problem 40 「チャンパーノウン定数」 †

Problem 40 「チャンパーノウン定数」 

正の整数を順に連結して得られる以下の10進の無理数を考える:
0.123456789101112131415161718192021...
小数第12位は1である.
dnで小数第n位の数を表す. d1 × d10 × d100 × d1000 × d10000 × d100000 × d1000000 を求めよ.

求めるポイントを1,10,100、、、をpとして
http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2040


解法
(p-1-桁が上がるときのスタート桁数でpに一番近いpより小さなもの)/その時の桁数
でpを含む数字が求まり
(p-1)%桁数でその数字の何個めかがわかります。
それだけ。

list(Start,_,_,[]):-Start>1000*1000,!.
list(Start,Base9,M,[[Start,M1]|Result]):-
      !,
      Start1 is Start+Base9*(M+1),
      Base9a is Base9*10,
      M1 is M+1,
      list(Start1,Base9a,M1,Result).
list_w(Result):-
      list(9,90,1,Re),

      reverse([[0,1]|Re],Result).
calc_pos_num(P,List,AnsNum1):-
      P1 is P-1,
      member([SPos,Keta],List),
      SPos=<P1,
      !,
      P2 is (P1-SPos)//Keta,
      Num is 10^(Keta-1)+P2,
      P3 is P2 mod Keta,
      number_codes(Num,ListNum),
      nth0(P3,ListNum,AnsNum),
      AnsNum1 is AnsNum-48.
calc_pos_num_w(Poss,List,Result):-
      member(P,Poss),
      calc_pos_num(P,List,Result).

mult([],1):-!.
mult([X|Xs],Result):-
      !,
      mult(Xs,Re),
      Result is Re*X.

main40:-
      list_w(SPos),
        Poss=[1,10,100,1000,10000,100000,1000000],
      findall(E,calc_pos_num_w(Poss,SPos,E),AnsList),
      mult(AnsList,Ans),
      write(Ans).

0 件のコメント:

コメントを投稿