我写了一个序言程序来解决和显示数独之类的难题的解决方案。首先,如果网格为例如4x4,我会使用类似的方法:
main:-
Matrix = [[_,_,_,_],[_,_,_,_],[_,_,_,_],[_,_,_,_]],
solve_puzzle(Matrix),
display_matrix(Matrix).
Run Code Online (Sandbox Code Playgroud)
但是我希望能够设置矩阵的大小,所以我写了这样的代码:
generate_list(N, [ ]) :-
N =< 0, !.
generate_list(N, [_ | T]) :-
N > 0,
N2 is N - 1,
generate_list(N2, T).
generate_matrix(_, N, []) :-
N =< 0, !.
generate_matrix(M, N, [R|T]) :-
generate_list(M,R),
N2 is N - 1,
generate_matrix(M, N2, T).
Run Code Online (Sandbox Code Playgroud)
然后我可以做:
main:-
Rows = 4, Columns = 4,
generate_matrix(Columns,Rows,Matrix),
solve_puzzle(Matrix),
display_matrix(Matrix).
Run Code Online (Sandbox Code Playgroud)
但这似乎减慢了我的程序。有没有更好的方法来生成N x M矩阵?
的组合length/2和maplist/2运作良好的位置:
length_list(N, List) :- length(List, N).
generate_matrix(Cols, Rows, Matrix) :-
length_list(Rows, Matrix),
maplist(length_list(Cols), Matrix).
Run Code Online (Sandbox Code Playgroud)
我定义length_list/2了将length参数放在第一位,以便在中使用它maplist/2。
length/2是关系型的,因此当您length/2使用实例化的长度(例如N)进行调用时,但将list参数作为变量调用时,它将导致[_,_, ..., _]带有N元素。因此,第一个length_list创建的列表Matrix看起来像是[_, _, _, ..., _]length Rows。然后maplist/2,对于的每个元素(行R)Matrix,下面的调用length_list(Cols, R)将代替length 生成每个_列表。[_, _, ..., _]Cols
maplist/2将调用第一个参数作为第二个参数的每个元素的谓词,即列表。因为我们给它length_list(Cols),它呼吁,对于每一个元素[_, _, ..., _],call(length_list(Cols), _),这相当于,call(length_list(Cols, _)),这将实例_有[_, _, ..., _],长度为匿名变量列表Cols。
我使用SWI Prolog进行了一些快速的时间检查time/1,上述方法似乎要快得多。