Related
I'm trying to decode a given list for example mydecode([(a,1), (b,2), (c,3), (d,2)],X) should give X = ['a','b','b','c','c','c','d','d']. What is the error in this code?
mydecode([],[]).
mydecode([X|Ys],[X|Zs]) :- \+ is_list(X), mydecode(Ys,Zs).
mydecode([[1,X]|Ys],[X|Zs]) :- mydecode(Ys,Zs).
mydecode([[N,X]|Ys],[X|Zs]) :- N > 1, N1 is N - 1, mydecode([[N1,X]|Ys],Zs).
you are asked to handle a list of 'tuples' of 2 elements, not a list of lists of 2 elements
then, the test in the second clause will always fail
the tuples elements are key and value, but you're 'accessing' them in inverse order.
So, remove the second clause - it's irrelevant, since pattern matching will discard ill formed lists.
Change the [1,X] to (X,1) and similarly other references to tuples, and test your code with the query assigned.
How to change of list of tuples, like
[(5,6),(7,8),(9,10)]
into a normal list, like
[5,6,7,8,9,10]
via list comprehensions and without concat?
I have tried this:
[ [y, z] | xs <- [(1,2),(3,4)], y <- fst(xs), z <- snd(xs) ]
To flatten any list with a list comprehension, the form is always the same. Take the multiple elements from the source one-at-a-time.
List comprehensions, like functions let you specify and exact pattern of the source, tuple or list.
Your function is not in the form of multiples, one-at-a-time, so correcting it will never give you what you want. It will, at very least require the use of concat to concatenate the output.
Here is the form of a flattening list comprehension
[ n |(a,b)<-[(1,2),(3,4),(5,6)],n <-[a,b]]
a and b are taken one-at-a-time by n, to flatten.
This question already has answers here:
Shuffle in prolog
(2 answers)
Closed 5 years ago.
This is my first attempt at using recursion over lists on a non-sample program so bare with my inexperience!
Expected Valid Queries:
mixElements([],[a,b,c], [a,b,c]).
mixElements([a,b],[],[a,b]).
mixElements([a,b,c],[d,e,f],[a,d,b,e,c,f]).
mixElements([a,b,c],[d,e,f,g,h],[a,d,b,e,c,f,g,h]).
Here I tried to create the base case for when the inputs lists are empty, the Result is simply returned.
/* Base cases */
mixElements([],[],Result).
The logic for my recursive statement is that the input lists must be at least 1 or more elements. Thus they must both be represented by [H|L] respectively for list 1 and 2. Then it will append H1 and H2 to Result to create the alternating pattern of list elements. Finally it will call mixElements with the remainder of the lists, L1 and L2, and the Result list that should now contain the first head elements of both lists.
/* Recursive case where both L1 and L2 are not empty */
mixElements([H1|L1],[H2|L2],Result) :- append(H1,H2,Result), mixElements(L1,L2,Result).
My resulting output is always "no".
When dealing with lists it's usually worthwhile considering DCGs since they yield easily readable code. It further aids readability to choose a descriptive name for the relation, say list_list_interlocked/3. Consider the following code:
list_list_interlocked(L1,L2,I) :-
phrase(interlocked(L1,L2),I).
interlocked([],[]) --> % if both input lists are empty
[]. % the resulting list is also empty
interlocked([],[H2|T2]) --> % if the first input list is empty
[H2], % the head of the second is in the list
interlocked([],T2). % the relation holds for the tail as well
interlocked([H1|T1],[]) --> % if the second input list is empty
[H1], % the head of the first is in the list
interlocked(T1,[]). % the relation holds for the tail as well
interlocked([H1|T1],[H2|T2]) --> % if both lists are non-empty
[H1,H2], % the heads are in the list
interlocked(T1,T2). % the relation holds for the tails as well
Your example queries yield the desired result:
?- list_list_interlocked([],[a,b,c],I).
I = [a,b,c]
?- list_list_interlocked([a,b],[],I).
I = [a,b]
?- list_list_interlocked([a,b,c],[d,e,f],I).
I = [a,d,b,e,c,f]
?- list_list_interlocked([a,b,c],[d,e,f,g,h],I).
I = [a,d,b,e,c,f,g,h]
Basically there are four cases here:
the first list is empty, the second list is empty, in that case the result should be empty:
mixElements([],[],[]).
the first list is empty, the second list is non-empty, in that case, the result is the second list:
mixElements([],[H2|T2],[H2|T2]).
the first list is non-empty, the second list is empty, in that case, the result is the first list:
mixElements([H1|T1],[],[H1|T1]).
finall both lists are non-empty, in that case the two first elements of the result are the heads of the list, followed by mixing the tails of the lists:
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
Now we can put that all together into:
mixElements([],[],[]).
mixElements([],[H2|T2],[H2|T2]).
mixElements([H1|T1],[],[H1|T1]).
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
Now we have created some redundant statements. For instance we can merge the first two statements into one, like:
mixElements([],L,L).
mixElements([H1|T1],[],[H1|T1]).
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
I leave it as an exercise to further improve the predicate. You can for instance use cuts, but this can eliminate the multi-direction of the predicate, which is sometimes very useful.
You're using append/3 where it's not needed. When the pattern is formed by 2 lists of at least one element, you can get the result immediately, then recurse to handle the tails:
mixElements([H1|L1],[H2|L2],[H1,H2|Rest]) :-
!, mixElements(L1,L2,Rest).
mixElements(L1,L2,Rest) :- append(L1,L2,Rest).
First of all, I cannot remember the name of this repetition of list.
I have a list:
myList = [0, 1, 2]
I want to repeat list of list:
[[0,1,2],[1,2,0],...]
I know that I can do permutations myList
But it won't cover the repeated parts such as [[0,0,0],[1,1,1],[1,1,0],...]
So, my questions are what is the name given for such kind of list.
It is not permutations and it definitely is not combinations
In logic, we call it truth table, I believe.
And is there a builtin function for that in haskell?
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> :m +Control.Monad
Prelude Control.Monad> replicateM 3 [0,1,2]
[[0,0,0],[0,0,1],[0,0,2],[0,1,0],[0,1,1],[0,1,2],[0,2,0],[0,2,1],[0,2,2],[1,0,0],[1,0,1],[1,0,2],[1,1,0],[1,1,1],[1,1,2],[1,2,0],[1,2,1],[1,2,2],[2,0,0],[2,0,1],[2,0,2],[2,1,0],[2,1,1],[2,1,2],[2,2,0],[2,2,1],[2,2,2]]
Note that basically, the length of the list of permitted values needs in no way be connected to the length of each list of choices.
with list comprehension
x = [0,1,2]
[[a,b,c] | a<-x, b<-x, c<-x]
[[0,0,0],[0,0,1],[0,0,2],[0,1,0],[0,1,1],[0,1,2],[0,2,0],[0,2,1],[0,2,2],
[1,0,0],[1,0,1],[1,0,2],[1,1,0],[1,1,1],[1,1,2],[1,2,0],[1,2,1],[1,2,2],
[2,0,0],[2,0,1],[2,0,2],[2,1,0],[2,1,1],[2,1,2],[2,2,0],[2,2,1],[2,2,2]]
So I'm new to Erlang and still on the learning curve, one question asked was to return all elements in a list followed by an equal element, to which I could to.
For example...
in_pair_lc([a,a,a,2,b,a,r,r,2,2,b,a]) -> [a,a,r,2]
I was then asked to do the same using a list comprehension, and I hit my mental block.
My unsuccessful attempt was this:
in_pair_lc([]) -> [];
in_pair_lc([H|T]) ->
[X || X ,_ [H|T], X=lists:nth(X+1, [H|T]).
Although with no look ahead in list comp it doesn't work.
Thanks for any help in advance.
One way to do this with a list comprehension is to create two lists from the input list:
one containing all elements except the very first element
one containing all elements except the very last element
By zipping these two lists together, we get a list of tuples where each tuple consists of adjacent elements from the input list. We can then use a list comprehension to take only those tuples whose elements match:
in_pair_lc([_|T]=L) ->
[_|T2] = lists:reverse(L),
[H || {H,H} <- lists:zip(lists:reverse(T2),T)].
EDIT: based on the discussion in the comments, with Erlang/OTP version 17.0 or newer, the two list reversals can be replaced with lists:droplast/1:
in_pair_lc([_|T]=L) ->
[H || {H,H} <- lists:zip(lists:droplast(L), T)].
The first example will work on both older and newer versions of Erlang/OTP.
I'm not convinced the problem is really about list comprehensions. The core of the problem is zipping lists and then using a trivial "filter" expression in the list comprehension.
If you want to stick to basic, long existing, erlang list functions (sublist, nthtail) you could go with the following:
X = [a,a,a,2,b,a,r,r,2,2,b,a].
[A || {A,A} <- lists:zip(lists:sublist(X, length(X)-1), lists:nthtail(1, X))].