我写了一个序言程序来解决和显示数独之类的难题的解决方案。首先,如果网格为例如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
,上述方法似乎要快得多。