L=[[X,Y,Z],[1,A,B],[2,C,D]], L ins 1..3, all_different(L), label(L).
I just want to fill the variables in the lists of the list with values. Is there any solution to get the elements of the list (which are lists) in an easier way than get_element_at(L,1) and so on?
get_element(LL,M,N,Element) :-
length([_|L01],M),
length([_|L02],N),
append(L01,[L|_],LL),
append(L02,[Element|_],L).
Related
I'm trying to learn Elixir. In most other languages i've battled with, this would be an easy task.
However, i can't seem to figure out how to access a list item by index in Elixir, which i need for finding the median item in my list. Any clarification would be greatly appreciated!
You will want to look into Enum.at/3.
a = [1,2,3,4,5]
middle_index = a |> length() |> div(2)
Enum.at(a, middle_index)
Note: This is expensive as it needs to traverse the entire list to find the length of the list, and then traverse halfway through the list to find what the actual element is. Generally speaking, if you need random access to an item in a list, you should be looking for a different data structure.
This is how I would do it:
Enum.at(x, div(length(x), 2))
Enum.at/3 retrieves the value at a particular index of an enumerable. div/2 is the equivalent of the Python 2.x / integer division.
So I've been trying to implement this function in my module and so far I got this:
EXAMPLE 1.
[2,[3,[4,[5,[6,[7,[8,[]]]]]]]]
I am trying to figure out how I can make it look like a proper list, ie:
EXAMPLE 2.
[2,3,4,5,6,7,8].
I know I have to play with Heads and Tails but I am miserably failing at understanding it.
Any help would be appreciated.
Thanks!
Actually in the example 1 you show proper list. List that just consists of 2 elements - number and another list.
Improper list is different thing - for instance [1|2].
You can turn example 1 into example 2 by lists:flatten.
1> M = [2,[3,[4,[5,[6,[7,[8,[]]]]]]]].
[2,[3,[4,[5,[6,[7,[8,[]]]]]]]]
2> lists:flatten(M).
[2,3,4,5,6,7,8]
The root of the problem is how you have built your list. What you have here:
[2,[3,[4,[5,[6,[7,[8,[]]]]]]]]
is not one list but nested lists each of two elements. When you do [Element,List] this does NOT prepend Element to List but builds a new list with Element as the first element and List as the second element. Note that each list is a proper list but you have not built one list but nested lists.
To prepend Element to List you use the syntax [Element | List]. So:
[2|[3|[4|[5|[6|[7|[8|[]]]]]]]]
which builds the list [1,2,3,4,5,6,7,8].
So [Element | List] and [Element,List] are two very different things, the first prepends an element to the beginning of a list while the second builds a new list of two elements. There is no direct way of appending an element to a list without rebuilding the list.
Not as obvious as it looks at first, but this is a manual way of doing what lists:flatten/1 does (in this particular case, its more interesting otherwise):
proper(L) -> proper([], L).
proper(A, [H|[T]]) -> proper([H|A], T);
proper(A, []) -> lists:reverse(A).
I am new to prolog and I am trying to create a predicate and am having some trouble.
I have a list of cities that are connected via train. They are connected via my links/2 clause.
links(toronto, ajax).
links(toronto, markham).
links(toronto, brampton).
links(brampton, markham).
links(markham, ajax).
links(brampton, mississauga).
links(mississauga, toronto).
links(mississuaga, oakville).
links(oakville, st.catharines).
links(oakville, hamilton).
links(hamilton, st.catharines).
I am writing a predicate called addnewcities which will take a list of cities and then return a new list containing the original list, plus all the cities that are directly connected to each of the cities in the original list.
Here is a (rough looking) visual representation of the links.
If my input list was [toronto] I want my output to be (order doesnt matter) [ajax,markham,brampton,mississauga,toronto].
If input was [oakville,hamilton] I want the output to be [mississauga,st.catharines,oakville,hamilton].
Here is my predicate so far.
addnewcities([],_).
addnewcities([CitiesH|Tail],Ans):- directer(CitiesH,Ans2), merger(Ans2,[CitiesH],Ans), addnewcities(Tail,Ans).
directer/2 takes a city and saves a list containing all the directly connected cities in the second arg.
merger/3 just merges two lists making sure there are no duplicates in the final list.
When my input is a list with one element ie [toronto] it works!
But when I have a list with multiple elements [toronto,ajax] it says "false" every time.
I'm pretty sure my issue is that when it recurses for the second time, merge is what says its false. I just don't know how to get around this so that my list can keep being updated instead of being checked if true or false.
Any help is appreciated!
this query uses library support to solve the problem:
addcities(Cs, L) :-
setof(D, C^(member(C,Cs), (C=D;link(C,D);link(D,C))), L).
This should work for what you want:
addcities(A,B):-
addcitiesaux(A,[],B).
addcitiesaux([],X,X).
addcitiesaux([X|Xs],L,R):-
link(X,A),
\+ member(A,L),
!,
addcitiesaux([X|Xs],[A|L],R).
addcitiesaux([X|Xs],L,R):-
link(A,X),
\+ member(A,L),
!,
addcitiesaux([X|Xs],[A|L],R).
addcitiesaux([X|Xs],L,R):-
addcitiesaux(Xs,[X|L],R).
I have a list of lists. I need the elements inside reordered so that the new list of lists is a list of all the first elements, then a list of all the second elements, etc.
It should look like this:
Input
[[a1,a2,a3],[b1,b2,b3],[c1,c2,c3]]
Output
[[a1,b1,c1],[a2,b2,c2],[a3,b3,c3]]
Can anyone help me with this?
It looks like you want transpose, for which you need to import Data.List.
transpose will take the first elements of the lists that have them and put them in the first list in the right order, then the second elements of the lists that have them and put them in the second list in the right order, and so on.
For example,
> transpose [[1,2,3],[4,5],[6]]
[[1,4,6],[2,5],[3]]
> transpose [[1],[2,3],[4,5,6]]
[[1,2,4],[3,5],[6]]
In general when confronted with such issues :
Determine the type of the function you need, here [[a]] -> [[a]]
Search Hoogle http://www.haskell.org/hoogle/
Guess first result in your case ? transpose of course.
NB : You should accept answer from user3217013 - I wrote this because I can't edit yet
I have a list in prolog that contains several items. I need to 'normalized' the content of this list and write the result to a new list. But I still have problem in doing it.
The following code shows how I did it:
normalizeLists(SourceList, DestList) :-
% get all the member of the source list, one by one
member(Item, SourceList),
% normalize the item
normalizeItem(Item, NormItem),
% add the normalize Item to the Destination List (it was set [] at beginning)
append(NormItem, DestList, DestList).
The problem is in the append predicate. I guess it is because in prolog, I cannot do something like in imperative programming, such as:
DestList = DestList + NormItem,
But how can I do something like that in Prolog? Or if my approach is incorrect, how can I write prolog code to solve this kind of problem.
Any help is really appreciated.
Cheers
Variables in Prolog cannot be modified, once bound by unification. That is a variable is either free or has a definite value (a term, could be another variable). Then append(NormItem, DestList, DestList) will fail for any NormItem that it's not an empty list.
Another problem it's that NormItem it's not a list at all. You can try
normalizeLists([], []).
normalizeLists([Item|Rest], [NormItem|NormRest]) :-
% normalize the item
normalizeItem(Item, NormItem),
normalizeLists(Rest, NormRest).
or (if your Prolog support it) skip altogether such definition, and use an higher order predicate, like maplist
...
maplist(normalizeItem, Items, Normalized),
...