※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

Problem 40 「チャンパーノウン定数」 †
正の整数を順に連結して得られる以下の10進の無理数を考える:

0.123456789101112131415161718192021...
小数第12位は1である.

dnで小数第n位の数を表す. d1 × d10 × d100 × d1000 × d10000 × d100000 × d1000000 を求めよ.




解法
一桁は9個めまで
2桁は180+9個めまで
3桁は2700+180+9個めまで続き以下同様です。
例えば3000なら2889個めの4桁の中に答えがあり、
4桁は4つ数字が延々ならぶので(111-1)/4+1000の数字の中に目的のポイントがあり。
そのポイントの数字の中の(p-1) mod 4桁目が答えとなります。


calcP(P,[S|_],Keta,ReNum,ReP):-
	P=<S,
	!,
	ReNum is (P-1)//Keta+10^(Keta-1),
	ReP   is (P-1) mod Keta 
	.
calcP(P,[S|Splits],Keta,ReNum,ReP):-
	P1 is P-S,
	Keta1 is Keta+1,
	calcP(P1,Splits,Keta1,ReNum,ReP).

calc(P,[ReNum,ReP]):-
	Splits=[9,180,2700,36000,450000,5400000],
	calcP(P,Splits,1,ReNum,ReP).
calc_list(Result):-
 	member(P,[1,10,100,1000,10000,100000,1000000]),
	calc(P,[Num,P1]),
	num_to_list(Num,List),
	reverse(List,List1),
	nth0(P1,List1,Result).

num_to_list(0,[]):-!.
num_to_list(N,[X|Result]):-
 	N1 is N//10,
	X  is N mod 10,
	num_to_list(N1,Result).

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

main40:-findall(A,calc_list(A),Ansers),
        mults(Ansers,Ans),
	write(Ans).