列出Prolog中矩阵的对角线

Jon*_*h P 1 list prolog

我如何n*n在Prolog中获得一个大小矩阵的对角线列表?

预期行为:

?- diagonal1([[1,3,2],[4,5,7],[6,8,9]],D1). 
D1=[1,5,9]
?- diagonal2([[1,3,2],[4,5,7],[6,8,9]],D2). 
D2=[2,5,6].
Run Code Online (Sandbox Code Playgroud)

(我使用内置函数很好.)

cod*_*der 6

这是我的解决方案foldl/4:

extract_element(L, L1, [H|L1]):- 
                length(L1, N1), 
                length(L2, N1), 
                append(L2, [H|_], L).

diagonal1(In, Out):- 
                foldl(extract_element, In, [], Res), 
                reverse(Res,Out).

diagonal2(In, Out):- 
                reverse(In, In2),
                foldl(extract_element, In2, [], Out).
Run Code Online (Sandbox Code Playgroud)

你可以看到在现货的差异diagonal1/2diagnal2/2实现?

diagonal1/2我们foldl/4以相反的顺序返回Res变量中的结果表单所需的顺序,因此我们反转结果以获得正确的列表.另一方面,diagonal2/2foldl/4通过反转输入列表来理解上面的工作方式,我们不仅能够提取正确的元素,而且现在返回的逆序foldl/4是正确的!

例:

?- diagonal1([[1,3,2],[4,5,7],[6,8,9]],D1).
D1 = [1, 5, 9].

?- diagonal2([[1,3,2],[4,5,7],[6,8,9]],D2).
D2 = [2, 5, 6]. 
Run Code Online (Sandbox Code Playgroud)


rep*_*eat 5

使用 maplist/3和常用的reverse/2:

list_diag1([], []).
list_diag1([[E|_]|Ess], [E|Ds]) :-
    maplist(list_tail, Ess, Ess0),
    list_diag1(Ess0, Ds).

list_tail([_|Es], Es).

list_diag2(Ess,Ds) :-
    maplist(reverse, Ess, Fss),
    list_diag1(Fss, Ds).
Run Code Online (Sandbox Code Playgroud)

示例查询:

?- list_diag1([[a,b,c],[d,e,f],[g,h,i]], D1).
D1 = [a,e,i].

?- list_diag2([[a,b,c],[d,e,f],[g,h,i]], D2).
D2 = [c,e,g].
Run Code Online (Sandbox Code Playgroud)