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

Problem 107 「最短ネットワーク」 †
http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%20107
グラフ理論の最短経路の問題。


解法
Prolog言語でプリム法は少し効率が悪いがプリム法の処理本体は書く前はどうなるかわからなかったが書いてみると結構シンプルになった。
行列サイズ40決め打ちである。
データは一行一リスト、2次元配列風の40行で40リストに変換してからテキストファイルに保存した。

oks(_,[0,_]):-!,fail.
oks(Commit,[_,No]):-!,
	not(member(No,Commit)).

calc(Commit,_,_,Sum,AllSum):-
	length(Commit,40),
	!,
 	Ans is AllSum-Sum,
	write(Ans).
calc(Commit,Cons,List,Sum,AllSum):-
	select(Con,Cons,Cons1),
	oks(Commit,Con),
	!,
	[Cost,No]=Con,
	Sum1 is Sum+Cost,
	nth1(No,List,AddCon),
	append(Cons1,AddCon,Cons2),
	msort(Cons2,Cons3),
	calc([No|Commit],Cons3,List,Sum1,AllSum).

row_change([],_,[]):-!.
row_change([-|Xs],No,[[0,No]|Result]):-
	!,
	No1 is No+1,
	row_change(Xs,No1,Result).
row_change([X|Xs],No,[[X,No]|Result]):-
	!,
	No1 is No+1,
	row_change(Xs,No1,Result).

sum([],Sum,Sum):-!.
sum([X,_|Xs],Sum,Result):-
	Sum1 is Sum+X,
	sum(Xs,Sum1,Result).


main:-
	see('pe107.txt'),
	read(D),
	seen,
	findall(E,(member(E1,D),row_change(E1,1,E)),D2),
	flatten(D2,D3),
	sum(D3,0,AllSum),
	AllSum2 is AllSum//2,
	member(R,D2),
	!,
	msort(R,R1),
	calc([1],R1,D2,0,AllSum2).
最終更新:2015年01月20日 01:58