Here we go, bear with me. The over-all goal is to return the max alignment between two lists. If there are more than one alignment with the same length it can just return the first.
With alignment I mean the elements two lists share, in correct order but not necessarily in order. 1,2,3 and 1,2,9,3; here 1,2,3 would be the longest alignment. Any who, know for the predicates that I already have defined.
align(Xs, Ys, [El | T]) :-append(_, [El | T1], Xs),append(_, [El | T2], Ys),align(T1, T2, T).
align(_Xs, _Ys, []).
Then I use the built-in predicate findall to get a a list of all the alignments between these lists? In this case it puts the biggest alignment first, but I'm not sure why.
findall(X,align([1,2,3],[1,2,9,3],X),L).
That would return the following;
L = [[1, 2, 3], [1, 2], [1, 3], [1], [2, 3], [2], [3], []].
That is correct, but now I need a predicate that combines these two and returns the biggest list in the list of lists.
Use the solution given in this answer.
You could also try to avoid using findall/3,
because you don't really need to build a list in order to find its largest element.
So you just need to find the largest item in the list?
Edit:
Ok, so a better answer is this:
If you care about performance, then you need to write your own predicate which scans the list keeping track of the largest item.
If you don't carte so much about performance and you just want it to work, you could just reverse sort it and then take the first item in the sorted list. The advantage of this is that by using a sort library predicate you should be able to implement it in a few lines.
Related
I have one list of lists like this: [[a,b],[b,c],[c,d]] and I want to has [a,b,c].
My code is:
unMakeTuple([],_).
unMakeTuple([[A,_]|T],Ret):-
insertOnList(A,Ret,Ret1),
nl,write(Ret),
nl,write(Ret1),
unMakeTuple(T,Ret1).
insertOnList(E,[],[E]).
insertOnList(E,[H|T],[H|T1]):-
insertOnList(E,T,T1).
And return me a empty list.
Someone can help me?
Thank you.
You here want basically make a mapping where we obtain the head of every sublist.
So we can define a predicate head/2:
head([H|_],H).
and then use maplist/3:
unMakeTuple(A,B) :-
maplist(head,A,B).
then we obtain:
?- unMakeTuple([[a,b],[b,c],[c,d]],X).
X = [a, b, c].
Although writing a custom predicate can of course be beneficial as well. The advantage here is that (a) it is very declarative and easy to understand that we map a list A to a mapB by for each element unify the elements of the two lists by the head predicate; (b) we can be quite certain that maplist/3 works correctly and (c) we can expect that maplist/3 will be optimized such that processing is done fast.
#Willem Van Onsem's solution using maplist/3 above is the better way to do this, but another way to do this is to just write a predicate that adds all the heads of the inner lists to a resulting list. Some sort of recursive solution like this should work:
head([H|_], H).
get_heads([], []).
get_heads([X|Xs], List) :-
head(X, H),
List = [H|Rest],
get_heads(Xs, Rest).
Which works as follows:
?- get_heads([[a,b],[b,c],[c,d]], X).
X = [a, b, c].
How can I construct a list of a list into one single list with interleaving sublists?
like recons([[1,2],[3,4]],X) will give X= [1,3,2,4]?
I have been trying hours and my code always gave me very strange results or infinite loop,
what I thinking was something like this:
recons([[A|R],REST],List):-
recons(R,REST),
append(A,[R|REST],List).
I know its completely wrong, but I don`t know how to fix this.
Instead of thinking about efficiency first, we can think about correctness first of all.
interleaving_join( [[]|X], Y):-
interleaving_join( X, Y).
that much is clear, but what else?
interleaving_join( [[H|T]|X], [H|Y]):-
append( X, [T], X2),
interleaving_join( X2, Y).
But when does it end? When there's nothing more there:
interleaving_join( [], []).
Indeed,
2 ?- interleaving_join([[1,2],[3,4]], Y).
Y = [1, 3, 2, 4] ;
false.
4 ?- interleaving_join([[1,4],[2,5],[3,6,7]], X).
X = [1, 2, 3, 4, 5, 6, 7] ;
false.
This assumes we only want to join the lists inside the list, whatever the elements are, like [[...],[...]] --> [...]. In particular, we don't care whether the elements might themselves be lists, or not.
It might sometimes be interesting to collect all the non-list elements in the inner lists, however deeply nested, into one list (without nesting structure). In fact such lists are actually trees, and that is known as flattening, or collecting the tree's fringe. It is a different problem.
I'm trying to increment every element of list by its depth. For example:
foo([0, 0, [0]], [1, 1, [2]]) -> true
Also, I'd like to do that without any built-in Prolog list predicates. Any ideas on how to solve this?
For divide_half, you need to verify 2 things (which can be done independently): that the lists define some kind of split, and that parts of the split have close enough lengths.
For the second, start by trying to FIND each element, then modify that to track the depth, and finally modify THAT to build up a copy of the list w/ the elements modified (though I don't understand what it means to one-increment something by a number).
This definition divides a list without any built-in predicates:
halve(List, A, B) :- halve(List, List, A, B).
halve(B, [], [], B).
halve(B, [_], [], B).
halve([H|T], [_,_|T2], [H|A], B) :-
halve(T, T2, A, B).
i just want to know if anyone of you knows whats faster,
L=[1,2,3,4,5], all_different(L). % needs use_module(library(clpfd)).
or
L=[1,2,3,4,5], is_set(L).
anyone knows? need the faster solution for my sudoku solver. thanks!
Use the predicate time/1 to measure the number of inferences and actual time taken to do the computation.
In your example you would do something like
time((L=[1,2,3,4,5], all_different(L))) vs. time((L=[1,2,3,4,5], is_set(L)))
Note that the time measured is up to the first success.
A distinction between all_different/1 and is_set/1 is that the former uses "constraint logic" and can impose a prospective restriction before the entries of a list are fully instantiated, such that failure occurs when the Prolog engine is compelled to unify or assign equal values to two of the list argument's entries.
We can illustrate the "constraint logic" of all_different with the following pair of queries:
?- length(L,5), all_different(L), L=[1,2,3,4,5].
L = [1, 2, 3, 4, 5].
?- length(L,5), all_different(L), L=[1,2,3,4,1].
false.
It is necessary to provide a proper list to all_different but not to have one of fully bound or "ground" entries. The above shows that all_different can prospectively impose a constraint on a list's entries.
Compare the results with is_set instead:
?- length(L,5), is_set(L), L=[1,2,3,4,5].
L = [1, 2, 3, 4, 5].
?- length(L,5), is_set(L), L=[1,2,3,4,1].
L = [1, 2, 3, 4, 1].
Once is_set succeeds, it cannot prevent future bindings that created equal entries.
So the predicate all_different relies on extra machinery in the constraint logic library to do what is_set cannot, and in most cases this extra machinery will add to the overhead. However in the simple way it was used in viktor's question, the extra machinery is not used very much. Checks are done on fully bound terms, not in a prospective manner, and the efficiency is comparable.
I have a list:
let a = [1, 2, 3]
I need to get another list:
[1, 2, 3] ++ [1*2, 2*3, 1*3] ++ [1*2*3]
It is a product of all possible unique coombinations of list's elements. I have founded permutations in Data.List, but as I see it is something different.
Is there any library functions to get this list or can you give me examles how can I create your own function.
Thanks.
For a library function, you can use subsequences from Data.List:
Prelude Data.List> subsequences [1,2,3]
[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
You can get all of the products using map product $ subsequences [1,2,3].
But that is not in the same order as you specified. So you can sort it,
using sortBy from Data.List and comparing from Data.Ord:
Prelude Data.List Data.Ord> sortBy (comparing length) $ subsequences [1,2,3]
[[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]
Again, get the products using map product.
Your other idea, to write a function yourself, is
the best idea if you are learning Haskell. Give it a try!
You want all subsequences, not permutations. Permutations give you all possible orders of the same elements. Whereas a subsequence is any sequence that has a subset of elements of the original, in the same order.
In addition to the function mentioned above, there's a clever trick to do this with some other library functions, but I'm not sure how helpful it will be to you.
import Control.Monad (filterM)
subsequences' :: [a] -> [[a]]
subsequences' = filterM $ const [False, True]
This trick takes advantage of the viewpoint of the list monad as modeling non-deterministic calculation. For each element in the list, it's included or not, non-deterministically, regardless of what it is.
It's efficient, and precisely the kind of thing the list monad is designed for, but it's somewhat opaque. You would probably learn more from implementing the same idea directly, based on the descriptions I've provided.