Search for the second minimum value in the list

I defined a predicate that finds the minimum value in a list, e.g.

greater(X,Y):- X > Y.
isLower(X,Y):- X < Y.


findmin( [X]   , X ).
findmin( [H|T] , P ):- findmin(T,P1) , isLower(H,P1), P is H.
findmin( [H|T] , P) :- findmin(T,P1) , greater(H , P1), P is P1.

However, it is difficult for me to modify this code to find the second minimum value, including nested lists.

How can I guarantee that the second minimum value will be returned?

+4
source share
3 answers

I mean this mostly as a joke, but here it is:

find_second_min(L, Min2) :- sort(L, [_, Min2|_]).

So, sorting will certainly put all your items in order. You can get a minimum just by looking at the top. If you want the two smallest, you can look at the first two elements:

find_mins(L, Min1, Min2) :- sort(L, [Min1, Min2|_]).

, - O (N log N), O (N). , , , , . .

+4

P , . , , P, , . , , .

, greater/isLower - , >/< ?

, , H P1.

, :

find2nd([H1, H2 | T], M) :- H1 < H2, !, find2nd_i(T, M, [H1, H2]).
find2nd([H1, H2 | T], M) :- H1 >= H2, find2nd_i(T, M, [H2, H1]).

find2nd_i([], M2, [_, M2]).
find2nd_i([H | T], M, [M1, M2]) :- H >= M2, !, find2nd_i(T, M, [M1, M2]).
find2nd_i([H | T], M, [M1, M2]) :- H < M2, H >= M1, !, find2nd_i(T, M, [M1, H]).
find2nd_i([H | T], M, [M1, M2]) :- H < M2, H < M1, find2nd_i(T, M, [H, M1]).
+3

-, findmin/2 :

findmin([H|T],P):- findmin(T,P1) , isLower(H,P1), P is H.

. .

- @DanielLyons , , O (n log n) . C Prolog; , , apporach .

@FelixDombek, . :

:

find2nd([H1,H2|T],Min2) :-
    H1 =< H2 ->
    find2nd(T,H1,H2,Min2)
   ;find2nd(T,H2,H1,Min2).

find2nd([],_,Min2,Min2).
find2nd([H|T],H1,H2,Min2) :-
    H >= H2 ->
    find2nd(T,H1,H2,Min2)
   ;(  H >= H1 ->
       find2nd(T,H1,H,Min2)
      ;find2nd(T,H,H1,Min2)
    ).
+1
source

Source: https://habr.com/ru/post/1665795/


All Articles