- 论坛徽章:
- 0
|
最近在看《七周七语言》,这类题用prolog是最合适的,而perl有AI: rolog,写了个代码,因为要完成穷举和满足所有条件,运行时间会有点久。
fd_domain与fd_all_diff函数都是自己写的,另个解决问题的方式是通过递归来实现的。
- use AI::Prolog;
- use Data::Dumper;
- $Data::Dumper::Indent = 0;
- my $prolog;
- # If reading from DATA, we need a CHECK block to ensure that
- # DATA is available by the time the constructor is called
- CHECK {
- $prolog = AI::Prolog->new(
- do { local $/; <DATA> }
- );
- }
- #[4, 9,2,
- # 3,5,7,
- # 8, 1,6]
- $prolog->query("sudoku([_, _,_,_,_,_,_, _,_], Solution).");
- #显示执行过程
- #$prolog->trace(1);
- while ( my $results = $prolog->results ) {
- #print "@$results\n";
- print Dumper $results;
- }
- __DATA__
- member(X, [ X | _ ]).
- member(X, [ _ | TAIL ]) :-
- member(X, TAIL).
- fd_domain([],_).
- fd_domain([ HEAD | TAIL ],L) :-
- member(HEAD,L),
- fd_domain(TAIL,L).
- fd_all_diff([]).
- fd_all_diff([ HEAD | TAIL ]) :-
- not(member(HEAD,TAIL)),
- fd_all_diff(TAIL).
- sum([], 0).
- sum([Head|Tail],Total) :-
- sum(Tail,Sum),
- Total is Head + Sum.
-
- valid([]).
- valid([HEAD|TAIL]) :-
- sum( HEAD , Total),
- eq(15,Total),
- valid(TAIL).
- sudoku(Puzzle, Solution) :-
- Solution = Puzzle,
- eq(Puzzle, [S11, S12, S13, S21, S22, S23, S31, S32, S33]),
- fd_domain(Solution, [1,2,3,4,5,6,7,8,9]),
- eq(Row1,[S11, S12, S13]),
- eq(Row2,[S21, S22, S23]),
- eq(Row3,[S31, S32, S33]),
- eq(Col1,[S11, S21, S31]),
- eq(Col2,[S12, S22, S32]),
- eq(Col3,[S13, S23, S33]),
- eq(ObjLineL,[S11, S22, S33]),
- eq(ObjLineR, [S13, S22, S31]),
- fd_all_diff(Solution),
- valid([Row1, Row2, Row3, Col1, Col2, Col3, ObjLineL, ObjLineR]).
复制代码 |
|