Взять максимум и минимум из списка и вычислить разницу в прологе - PullRequest
0 голосов
/ 27 апреля 2018

Возникли проблемы с получением кода для работы. Я чувствую, что проблема в вспомогательной функции dia1. Просто интересно, где я допустил ошибку?

append([],L,L). 
append([H|T],L2,[H|L3])  :-  append(T,L2,L3).


dia([H|T],N):-
    dia1(H,T,null,N).

dia1(_,_,N,N).

dia1(H,[H1|T1],_,N):-
    H>H1,
    X is H-H1,
    append(T1,[H1],L1),
    dia1(H,L1,X,N).

dia1(H,[H1|T2],_,N):-
    H=<H1,
    X is H-H1,
    append(T2,[H],L2),
    dia1(H1,L2,X,N).


Example test:
dia( [ 1, 5, 3, 1 ], 4 ) 
True
dia( [ 5, 5, 5 ], 0 ) 
True

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Это можно сделать в ближайшее время:

dial([H|T], R) :-
    dial(T, H, H, Min, Max),
    R is Max - Min.

dial([], Min, Max, Min, Max).

dial([H | T], Cur_Min, Cur_Max, Min, Max) :-
    H < Cur_Min
    -> dial(T, H, Cur_Max, Min, Max)
    ;  H > Cur_Max
       -> dial(T, Cur_Min, H, Min, Max)
       ;  dial(T, Cur_Min, Cur_Max, Min, Max).

например:

?- dial( [ 1, 5, 3, 1 ], X ) .
X = 4.

С библиотекой clfpd мы получаем:

:- use_module(library(clpfd)).


dial([H|T], R) :-
    dial(T, H, H, Min, Max),
    R #= Max - Min.

dial([], Min, Max, Min, Max).

dial([H | T], Cur_Min, Cur_Max, Min, Max) :-
    H #< Cur_Min
    -> dial(T, H, Cur_Max, Min, Max)
    ;  H #> Cur_Max
       -> dial(T, Cur_Min, H, Min, Max)
       ;  dial(T, Cur_Min, Cur_Max, Min, Max).

Например:

?- dial( [ 1, 5, 3, 1 ], X ) .
X = 4.

?- dial( [ 1, X, 3, 1 ], 4 ) .
X = -1.

?- dial( [ 1, X, 3, Y ], 4 ) .
X = 0,
Y = -1.

?- dial( [ A, B, C, D ], 4 ) .
4+D#=A,
B#=<A+ -1,
D#=<C+ -1,
C#=<B+ -1.
0 голосов
/ 27 апреля 2018

Ваша программа довольно грязная и не дает правильного результата. Например:

? - dia([1,5,3,1],A).
A = null
A = -4
A = 2
A = 4
A = 4
A = 2
A = 4
and so on...

Это должно дать только A = 4.

Вы можете упростить свой код, создав два предиката, например my_maxlist/2 и my_minlist/2, чтобы получить минимальное и максимальное значения списка, а затем вычесть значения, как показано ниже:

solve(L,Diff):-
    my_minlist(L,Min),
    my_maxlist(L,Max),
    Diff is Max-Min.

my_minlist([A],A):- !.
my_minlist([H|T],Min):-
    my_minlist_(T,H,Min).

my_maxlist([A],A):- !.
my_maxlist([H|T],Max):-
    my_maxlist_(T,H,Max).

my_minlist_([],Min,Min).
my_minlist_([H|T],CurrentMin,Min):-
    CurrentMin < H, !,
    my_minlist_(T,CurrentMin,Min).
my_minlist_([H|T],_,Min):-
    my_minlist_(T,H,Min).

my_maxlist_([],Min,Min).
my_maxlist_([H|T],CurrentMax,Min):-
    CurrentMax > H, !,
    my_maxlist_(T,CurrentMax,Min).
my_maxlist_([H|T],_,Min):-
    my_maxlist_(T,H,Min).

Имейте в виду, что min_list/2 и max_list/2 являются частью library(lists) в прологе SWI, поэтому уже определены, и вы можете просто написать:

solve(L,Diff):-
    min_list(L,Min),
    max_list(L,Max),
    Diff is Max-Min.

Запрос (в обоих случаях):

?- solve([4,3,1,7],D).
D = 6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...