我需要创建一个程序来检查列表是否增加然后减少,就像下面的例子中一样:
[1,2,3,4,5,6,4,3,2,1]
并且必须至少增加或减少一步。
基本上:
我想到找到列表中的最大数字,然后将列表拆分成两个列表,然后检查它们是否都已排序。如何更轻松地完成?
答案 0 :(得分:1)
以下是如何做到这一点:
up_and_down([A, B, C|Rest]) :-
A < B, up_and_down([B, C|Rest]).
up_and_down([A, B, C|Rest]) :-
A < B, B > C, goes_down([C|Rest]).
goes_down([]).
goes_down([X]).
goes_down([A, B|Rest]]) :-
A > B, goes_down([B | Rest]).
第一个谓词检查序列是否正在上升。当我们到达拐点时,第二个是真的。在那之后,我们只需检查它是否会一直持续到最后(最后三个)。
答案 1 :(得分:1)
如果使用的所有数字都是整数,请考虑使用clpfd!
:- use_module(library(clpfd)).
根据up_down_zs/3
,我们可以像这样定义std::getline(annotationsFile, firstLine)
:
up_down_zs(Up, [P|Down], Zs) :- Up = [_,_|_], Down = [_|_], append(Up, Down, Zs), append(_, [P], Up), chain(Up, #<), chain([P|Down], #>).
首先,我们所有的某些情况会导致失败:
?- member(Zs, [[1,1],[1,2,2,1],[1,2,3,4],[1,2,3,4,5,5,6,4,3,2,1]]), up_down_zs(_, _, Zs). false.
现在,让我们运行一些可以满足的查询!
?- up_down_zs(Up, Down, [1,2,3,4,5,6,4,3,2,1]). ( Up = [1,2,3,4,5,6], Down = [6,4,3,2,1] ; false ). ?- up_down_zs(Up, Down, [1,2,3,1]). ( Up = [1,2,3], Down = [3,1] ; false ). ?- up_down_zs(Up, Down, [1,2,1]). ( Up = [1,2], Down = [2,1] ; false ).
答案 2 :(得分:0)
或者:
pyramid(L) :-
append(Increase, Decrease, L),
( append(_, [Last], Increase), Decrease = [First|_]
-> Last > First
; true),
forall(append([_, [A, B], _], Increase), A < B),
forall(append([_, [C, D], _], Decrease), C > D),
!.
这要求您的实现定义了append/2
谓词,例如,如果您使用swi就是这种情况。但使用append/3
的改编并不难编码。