user1118501
user1118501

Reputation: 71

Prolog check if the list is like 1,2,3,4,2,1

I need to create a program to check if a list increases then decreases, just like in the example below:

[1,2,3,4,5,6,4,3,2,1]

and it must be at least a one step increase or decrease.

Basically:

I thought about finding the biggest number in the list and then splitting the list into two lists, then checking if they are both sorted. How can it be done easier?

Upvotes: 1

Views: 1365

Answers (3)

repeat
repeat

Reputation: 18726

If all numbers used are integers, consider using !

:- use_module(library(clpfd)).

Based on chain/2, we can define up_down_zs/3 like this:

up_down_zs(Up, [P|Down], Zs) :-
   Up = [_,_|_],
   Down = [_|_],
   append(Up, Down, Zs),
   append(_, [P], Up),
   chain(Up, #<),
   chain([P|Down], #>).

First, some cases we all expect to fail:

?- 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.

Now, let's run some satisfiable queries!

?- 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
).

Upvotes: 1

m09
m09

Reputation: 7493

Alternatively :

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),
    !.

That requires your implementation to have an append/2 predicate defined, which is the case if you use swi for example. An adaptation to use append/3 isn't hard to code though.

Upvotes: 0

angus
angus

Reputation: 2367

Here is how you can do it easier:

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]).

The first predicate checks whether the sequence is going up. When we get to the inflexion point, the second one is true. After that, we just have to check that it goes down until the end (last three).

Upvotes: 1

Related Questions