我想获取包含具有给定列索引和行索引的元素的矩阵的左右对角线。
例如:
rightDiagonal([[1,2,3],[4,5,6],[7,8,9]], 1, 0, Diagonal).
Diagonal = [2,4]
leftDiagonal([[1,2,3],[4,5,6],[7,8,9]], 1, 0, Diagonal).
Diagonal = [4,8]
谢谢。
这是我的尝试:
left_diagonal_left(Board, 0, Column_Index, List, New_List) :-
get_value_from_matrix(Board, Row_Index, Column_Index, Value),
append(List, Value, New_List).
left_diagonal_left(Board, Row_Index, 0, List, New_List) :-
get_value_from_matrix(Board, Row_Index, Column_Index, Value),
append(List, Value, New_List).
left_diagonal_left(Board, Row_Index, Column_Index, List, New_List) :-
get_value_from_matrix(Board, Row_Index, Column_Index, Value),
append(List, Value, New_List),
R = Row_Index - 1,
C = Column_Index - 1,
left_diagonal_left(Board, R, C, New_List, Newer_List).
left_diagonal_right(Board, 6, Column_Index, List, New_List).
left_diagonal_right(Board, Row_Index, 6, List, New_List).
left_diagonal_right(Board, Row_Index, Column_Index, List, New_List) :-
get_value_from_matrix(Board, Row_Index, Column_Index, Value),
append(List, Value, New_List),
R = Row_Index + 1,
C = Column_Index + 1,
left_diagonal_right(Board, R, C, New_List, Newer_List).
left_diagonal(Board, Row_Index, Column_Index, List, Newer_List) :-
left_diagonal_left(Board, Row_Index, Column_Index, List, New_List),
R = Row_Index + 1,
C = Column_Index + 1,
left_diagonal_right(Board, R, C, New_List, Newer_List).
问题在于append()失败。
答案 0 :(得分:0)
我们可以创建一个可以在两个方向(向左和向右)行走的通用谓词。
我们这里基本上需要两个参数: first 列的索引和行进的“方向”,“ {right”是-1
,{{ 1}}代表“左”。
因此,我们可以实现一个谓词1
,该谓词将产生这种关系。
基本上,我们需要考虑三种情况:
因此我们可以通过以下方式实现此目标:
diagonal/4
现在我们可以通过以下方式获得对角线:
diagonal([], _, _, []).
diagonal([Row|Rest], Col, DCol, Result) :-
( nth0(Col, Row, El)
-> (Result = [El | R2],
Col2 is Col + DCol,
diagonal(Rest, Col2, DCol, R2))
; Result = []).
当然,以上内容尚未完成:由于在问题中,一个输入两个坐标。但是,如果我们采用正确的坐标,则对于坐标对?- diagonal([[4,5,6],[7,8,9]], 1, -1, Diagonal).
Diagonal = [5, 7].
?- diagonal([[1,2,3],[4,5,6],[7,8,9]], 1, -1, Diagonal).
Diagonal = [2, 4].
?- diagonal([[4,5,6],[7,8,9]], 0, 1, Diagonal).
Diagonal = [4, 8].
,这等效于(X, Y)
。左对角线相同:包含(X+Y, 0)
的对角线与包含(X, Y)
的对角线相同。但是请注意,(0, Y-X)
或X+Y
可能超出范围,因此我们可以首先对坐标进行“规范化”,但是如果坐标“过高”或“过低” ,因此,我们将需要删除一定数量的行,并且每次更新该行直到达到范围内的值。
因此,我们可以实现一个谓词,该谓词首先进行一些迭代,直到找到有效索引为止,然后将控制权传递给Y-X
谓词,例如diagonal/4
:
prediagonal/4
所以现在我们可以用prediagonal([], _, _, []).
prediagonal([Row|Rest], Col, DCol, Result) :-
Col2 is Col + DCol,
( nth0(Col, Row, El)
-> (Result = [El | R2],
diagonal(Rest, Col2, DCol, R2))
; prediagonal(Rest, Col2, DCol, Result)).
来写left_diagonal/4
和right_diagonal
:
prediagonal/4
然后这给了我们
left_diagonal(M, R, C, Diagonal) :-
Delta is C-R,
prediagonal(M, Delta, 1, Diagonal).
right_diagonal(M, R, C, Diagonal) :-
Delta is R+C,
prediagonal(M, Delta, -1, Diagonal).
以上并不是最优雅的解决方案。最好将“ ?- right_diagonal([[1,2,3],[4,5,6],[7,8,9]], 1, 0, Diagonal).
Diagonal = [2, 4].
?- left_diagonal([[1,2,3],[4,5,6],[7,8,9]], 1, 0, Diagonal).
Diagonal = [4, 8].
”和“ diagonal/4
”合并到一个谓词中。我将其保留为练习。