Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding second min value in list

Tags:

prolog

I have defined the predicate that finds the minimum value in 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 i have hard time modifying this code to find second minimum value including nested lists.

How could i assure that the second minimum value will be returned?

like image 968
Darlyn Avatar asked Jun 21 '26 23:06

Darlyn


2 Answers

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

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

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

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

As you know, sorting is O(N log N) while you can find just the minimum in O(N). So to find just one value this is probably too much work. But it's cute.

like image 98
Daniel Lyons Avatar answered Jun 23 '26 18:06

Daniel Lyons


You could simply make P a list containing the two smallest numbers. Then you would need to check for each element if it is smaller than the larger one in P, and if so, replace it. Then in the end, the larger of the two is the second largest element.

By the way, you really don't need to define your own greater/isLower – why not just use the operators that are built in, >/< in their place?

This would also make it a bit easier to spot the bug you have in your code if H is exactly as large as P1.

So, here's how I would do it:

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]).
like image 32
Felix Dombek Avatar answered Jun 23 '26 17:06

Felix Dombek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!