プロジェクトオイラー問101

http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%20101
Problem 101 「最適多項式」 †
行列の掃き出し法に関する問題。

解法
掃き出し法をリストで自然に実装します。
配列と違ってリストは好き放題にアクセスできないので、処理の過程で行列を現すリストからいらないデータが掃き出されてリストが短くなる。
これを自然にかくとちょっと込み入った処理になりました。
writeは実装依存で表示が変わる、、、

calc(N,Re):-Re is 1-N+N^2-N^3+N^4-N^5+N^6-N^7+N^8-N^9+N^10.


seed2(A,N,Seed1):-
	A1 is A-1,
	findall(E,(between(0,A1,N2),E is N^N2),Seed),
	calc(N,Last),
	append(Seed,[Last],Seed1).
seed(N,Seed):-
	findall(E,(between(1,N,N1),seed2(N,N1,E)),Seed).


pivod_E1(_,[],[],[]):-!.
pivod_E1(T,[A|R],[B|R1],[C|Result]):-
	C is B-A*T,
	pivod_E1(T,R,R1,Result).

pivod_E(_,[],[]):-!.
pivod_E(R,[R1|Rest],[R2|Result]):-
	[T|A]=R,
	[T1|B]=R1,
	T2 is T1/T,
	pivod_E1(T2,A,B,R2),
	pivod_E(R,Rest,Result).

pivod([[_,_]],[]):-!.
pivod([X|Mat],[Top|Result]):-
	pivod_E(X,Mat,Mat1),
	!,
	[Top|_]=Mat1,
	pivod(Mat1,Result).

inner_rev([],[]):-!.
inner_rev([X|Xs],[X1|Result]):-
	reverse(X,X1),
	inner_rev(Xs,Result).

pivod2_E(_,_,[],[]):-!.
pivod2_E(N,D,[[N1,D1|Rest]|Mat],[[N2|Rest]|Result]):-
	N2 is N1-D1/D*N,
	pivod2_E(N,D,Mat,Result).


pivod2([],[]):-!.
pivod2([X|Mat],[N1|Result]):-
	[N,D]=X,
	pivod2_E(N,D,Mat,Mat1),
        N1 is N/D,
	pivod2(Mat1,Result).


calc2([],_,_,Sum,Sum):-!.
calc2([X|Xs],N,R,Sum,Result):-
	Sum1 is Sum+X*(N^R),
	R1 is R+1,
	calc2(Xs,N,R1,Sum1,Result).

pivodN(N,Result):-
	seed(N,Mat),
	pivod(Mat,Mat1),
	[Top|_]=Mat,
 	reverse([Top|Mat1],Mat2),
	inner_rev(Mat2,Mat3),
	pivod2(Mat3,Vec),
	reverse(Vec,Vec1),
 	N1 is N+1,
	calc2(Vec1,N1,0,0,Result).
 
sum([],Sum,Sum):-!.
sum([X|Xs],Sum,Result):-
	Sum1 is Sum+X,
	sum(Xs,Sum1,Result).
 

main:-
	findall(E,(between(0,10,N),pivodN(N,E)),Es),
 	sum(Es,0,Ans),
	write(Ans).
最終更新:2015年01月10日 10:27