sistemas - Verificación Prolog si la lista es como 1,2,3,4,2,1
prolog pdf (3)
Necesito crear un programa para verificar si una lista aumenta y luego disminuye, como en el siguiente ejemplo:
[1,2,3,4,5,6,4,3,2,1]
y debe ser al menos un aumento o disminución de un paso.
Básicamente:
- debe haber una única secuencia ascendente seguida de una secuencia descendente única.
- el paso en cada transición debe ser al menos uno (no hay números idénticos uno al lado del otro).
- el paso puede ser más de uno.
Pensé en encontrar el número más grande en la lista y luego dividir la lista en dos listas, luego verificando si ambas estaban ordenadas. ¿Cómo se puede hacer más fácil?
Alternativamente:
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),
!.
Eso requiere que su implementación tenga un predicado de append/2
definido, que es el caso si usa swi, por ejemplo. Sin embargo, una adaptación para usar append/3
no es difícil de codificar.
Aquí es cómo puedes hacerlo más fácil:
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]).
El primer predicado verifica si la secuencia está subiendo. Cuando llegamos al punto de inflexión, el segundo es verdadero. Después de eso, solo tenemos que verificar que baje hasta el final (los últimos tres).
Si todos los números utilizados son enteros, ¡considere usar clpfd !
:- use_module(library(clpfd)).
Basado en chain/2
, podemos definir up_down_zs/3
siguiente manera:
up_down_zs(Up, [P|Down], Zs) :- Up = [_,_|_], Down = [_|_], append(Up, Down, Zs), append(_, [P], Up), chain(Up, #<), chain([P|Down], #>).
Primero, algunos casos en los que todos esperamos fallar:
?- 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.
¡Ahora, ejecutemos algunas consultas satisfactorias !
?- 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 ).