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

https://projecteuler.net/problem=93
4つの自然数a<b<c<dと()と四則演算を使って数を作る。
数字の組によっては1から連続した自然数Nまでを作れるが。
1~Nまでが最も長くなるa,b,c,dの組み合わせを求めよ。

解法
1~9までの数字の範囲で全探索したら通りました。
端数処理を綺麗にしたかったので分数計算をしています。
記述の3割が分数計算の実装です。

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

add([U1,D1],[U2,D2],[U4,D4]):-
	U3 is U1*D2+U2*D1,
	D3 is D1*D2,
	abs(D3)>0,
	gcd(U3,D3,G),
	U4 is U3//G,
	D4 is D3//G.
dell(A,[U2,D2],C):-
	U3 is -U2,
	D3 is D2,
	add(A,[U3,D3],C).

mult([U1,D1],[U2,D2],[U4,D4]):-
	U3 is U1*U2,
	D3 is D1*D2,
	abs(D3)>0,
	gcd(U3,D3,G),
	U4 is U3//G,
	D4 is D3//G.

div([U1,D1],[U2,D2],[U4,D4]):-
	U2>0,
	mult([U1,D1],[D2,U2],[U4,D4]).

ope(A,B,C):-add(A,B,C).
ope(A,B,C):-dell(A,B,C).
ope(A,B,C):-mult(A,B,C).
ope(A,B,C):-div(A,B,C).


search([A,B],C):-ope(A,B,C).
search([A,B],C):-!,ope(B,A,C).
search(S,Result):-
	select(A,S,S1),
	select(B,S1,S2),
	select(C,S2,S3),
	select(D,S3,_),
	ope(A,B,A1),
	ope(C,D,C1),
	ope(A1,C1,Result).
search(S,Result):-
	select(A2,S,S1),
	search(S1,B2),
	ope(A2,B2,Result).
search(S,Result):-
	select(A2,S,S1),
	search(S1,B2),
	ope(B2,A2,Result).
 

ok([U1,D1],U2):-U1<0,D1=:=(-1),U2 is (-U1).
ok([U1,D1],U2):-U1>0,D1=:=1,U2 is U1.

perm(_,[A,B,C,D],[A,B,C,D]).
perm(10,_,_):-!,fail.
perm(N,Perm,Result):-
	N1 is N+1,
	perm(N1,Perm,Result).
perm(N,Perm,Result):-
	N1 is N+1,
	append(Perm,[[N,1]],Perm1),
	perm(N1,Perm1,Result).

count(N,[],N2):-!,N2 is N-1.
count(N,[N1|_],N2):-N<N1,!,N2 is N-1.
count(N,[N|Rest],Result):-
	N1 is N+1,
 	count(N1,Rest,Result).


searchPerm([Len,Perm]):-
	perm(1,[],Perm),
	findall(E,search(Perm,E),Es),
	sort(Es,Es1),
 	findall(E2,(member(E1,Es1),ok(E1,E2)),Es2),
	sort(Es2,Es3),
	count(1,Es3,Len).
main:-
	findall(E,searchPerm(E),Es),
 	sort(Es,Es1),
	append(_,[Ans],Es1),
	write(Ans).
最終更新:2015年02月13日 13:53