「プロジェクトオイラー問26」の編集履歴(バックアップ)一覧に戻る

プロジェクトオイラー問26 - (2014/02/14 (金) 04:50:30) の編集履歴(バックアップ)



Problem 26 「逆数の循環節 その1」 †

単位分数とは分子が1の分数である. 分母が2から10の単位分数を10進数で表記すると次のようになる.

1/2 = 0.5
1/3 = 0.(3)
1/4 = 0.25
1/5 = 0.2
1/6 = 0.1(6)
1/7 = 0.(142857)
1/8 = 0.125
1/9 = 0.(1)
1/10 = 0.1

0.1(6)は 0.166666... という数字であり, 1桁の循環節を持つ. 1/7 の循環節は6桁ある.

d < 1000 なる 1/d の中で小数部の循環節が最も長くなるような d を求めよ.



解法
1/pが循環するということは10^r mod P=1となるということで、
その候補はオイラーのファイ関数 fai(p-1)の約数が最小の条件を満たすrとなる。
これを探せばよい。


modPow(_,0,Result,_,Result):-!.
modPow(P,R,Mult,Pow10,Result):-
	R mod 2=:=1,
	!,
	R1 is R//2,
	Mult1 is (Mult*Pow10) mod P,
	Pow10_1 is (Pow10^2) mod P,
	modPow(P,R1,Mult1,Pow10_1,Result).
modPow(P,R,Mult,Pow10,Result):-
	!,
	R1 is R//2,
	Pow10_1 is Pow10^2,
	modPow(P,R1,Mult,Pow10_1,Result).

min(A,B,A):-A<B,!.
min(_,B,B):-!.
min_search([X],X):-!.
min_search([X|Xs],Result):-
	min_search(Xs,Re),
	min(X,Re,Result). 
yakusu(N,P,P):-N mod P=:=0.
yakusu(N,P,P1):-N>P*P,N mod P=:=0,!,P1 is N//P.

ok_yakusu_list(N,R):-
	NM is N-1,
 	between(1,NM,Div),
	Div2 is Div^2,
(NM < Div2 ->!,fail;true),
 	yakusu(NM,Div,R),
	modPow(N,R,1,10,Amari),
	Amari=:=1.
max_yakusu([MinY,N]):-
	between(2,999,N),
 	findall(Y,ok_yakusu_list(N,Y),Ys),
	min_search(Ys,MinY).
main26:-
	findall(X,max_yakusu(X),Xs),
	sort(Xs,Xs1),
	write(Xs1).