Related
Find all occurrences of {1, _}; in other words, all first element values that are 1 from each tuple in the list.
Consider the following input:
[
{1, 0},
{2, 2},
{1, 1},
{11, 1},
{1, 3},
{1, 2},
{13, 1}
]
Expected Output:
[{1,0}, {1,1}, {1,3}, {1,2}]
I tried Enum.find(tl(input), fn x -> elem(x, 0) == elem(hd(input), 0) end), but I realized that Enum.find/2 only returns the first and only one element that matches the criteria or function, which is: {1,1}.
My goal is to find all tuples that contain {1, _}, where the first element must be 1 and the second element can be any value.
Here you can use a comprehension with pattern-matching:
result = for x = {1, _} <- list, do: x
Any x that doesn't match the pattern {1, _} will be filtered out.
See the documentation for for/1 for more information.
You could also use Enum.filter/2 together with the match?/2 macro to achieve the same result:
result = Enum.filter(list, fn x -> match?({1, _}, x) end)
Enum.find/2 is useful when you are looking for a single element, e.g. if you want to find the first entry matching your condition.
I'm trying to move elements between Lists in LoL (list-of-list) structure.
I can figure out how to select the list and move the elements, but I'm lost on how to reconstruct the resulting LoL back.
Here is partial function :
move(From, To, State=[P1,P2,P3], NewState=[NP1, NP2, NP3]) :-
nth1(From, State, FL), nth1(To, State, TL), move_elem(FL, TL, NewFL, NewTL),
.....whats here?...
.. NewState should be build out of NewTL,NewFL and one of P1,P2,P3...
.. the order of the lists should be preserved..
move_elem/4 is implemented. From & To are integers and specify the lists-at-position that will participate in the move op.
Currently LoL is list of 3 lists, but I would like it in the future to parametrize the number of lists.
State is LoL before the move, NewState is the LoL after the move.
?- move_elem([1,2,3], [4,5,6], F,T).
F = [2, 3],
T = [1, 4, 5, 6].
nth1/3 seems to be working OK.
?- L=[[1,2],[3,4],[5,6]], nth1(2,L,El).
L = [[1, 2], [3, 4], [5, 6]],
El = [3, 4].
move() shold move element from one of the three lists to another.
From and To are the index-of-the-lists f.e.
LoL = [[1,2],[3,4],[5,6]]
move(1,3, LoL, NewLoL)
NewLoL = [[2],[3,4],[1,5,6]]
move(2,1, LoL, NewLoL)
NewLoL = [[3,1,2],[4],[1,5,6]]
move the top element from list-1 to list-3.
Using length/2 and append/3:
move(From, To, State, NewState):-
length([_|HState], From),
length([_|HNewState], To),
append(HState, [[Item|L]|TState], State),
append(HState, [L|TState], MState),
append(HNewState, [NL|TNewState], MState),
append(HNewState, [[Item|NL]|TNewState], NewState).
The idea is to use length/2 to produce a list on uninstantiated variables of length From-1 and another of length To-1 (thus we skip one element from the lists of length From and To).
Then append/3 can be used to split State in two parts or to concatenate two lists.
The first call to append will split State in a list HState of From-1 elements, and a second list with the rest. The first element from the rest is further split in two parts (the item to move and the rest of that element).
The second call to append joins the two parts excluding the item to be moved.
The third and fourth calls to append repeat this idea though this time they are used to add the moved item to the target location.
You can implement move/4 in this way:
appendHead(T,H,[H|T]).
removeHead([_|T],T).
insert(_,_,_,_,_,[],[]).
insert(C,I2,L1,L2,C,[_|TI],[L1|TO]):-
C1 is C+1,
insert(C,I2,L1,L2,C1,TI,TO).
insert(I1,C,L1,L2,C,[_|TI],[L2|TO]):-
C1 is C+1,
insert(I1,C,L1,L2,C1,TI,TO).
insert(I1,I2,L1,L2,C,[HI|TI],[HI|TO]):-
I1 \= C,
I2 \= C,
C1 is C+1,
insert(I1,I2,L1,L2,C1,TI,TO).
move(I1,I2,LIn,LOut):-
nth1(I1,LIn,L1),
nth1(I2,LIn,L2),
nth1(1,L1,E1),
removeHead(L1,L1R),
appendHead(L2,E1,L2F),
insert(I1,I2,L1R,L2F,1,LIn,LOut).
?- LoL = [[1,2],[3,4],[5,6]], move(1,3, LoL, NewLoL).
LoL = [[1, 2], [3, 4], [5, 6]],
NewLoL = [[2], [3, 4], [1, 5, 6]].
false.
?- LoL = [[2], [3, 4], [1, 5, 6]], move(2,1, LoL, NewLoL).
LoL = [[2], [3, 4], [1, 5, 6]],
NewLoL = [[3, 2], [4], [1, 5, 6]].
false.
?- LoL = [[1,2],[3,4],[5,6]], move(2,1, LoL, NewLoL).
NewLoL = [[3,1,2],[4],[1,5,6]].
false.
If you want to prevent backtracking, just add a cut ! after each definition of insert/4 (you will not get false).
Prolog does a depth-first search, meaning it will try to reach a goal by exploring all possible paths to a solution. Every time there are multiple paths available, it creates a choice point and then works its way down through the choices top to bottom. That means, if a choice immediately fails, the next will be called. This allows you to create the paths very clearly and you can give it choices to make. All atoms including lists are effectively immutable in Prolog. What you want to do is construct a second list from the first, possibly in a different order or with less elements, more elements, replaced elements etc.
I'm using replacement of a cell in a row with a cell(point(X,Y),Value) coordinate in a matrix as an example here. The three choices for rebuilding a list.
End of the list has been reached, this is the end condition and ends the new list.
The first cell of the list is checked and the coordinate doesn't match the replacement, so it's placed as is in the new list.
The first cell of the list does match the coordinate so place the element in the new list and close it off by adding the remaining unchecked elements as the tail.
This results in the code:
%coordinate not found, return the list as is
replace_cell(_,_,[],[]).
%no match, X already extracted from Element to reduce calls
replace_cell(X, Element, [RowElement|Tail], [RowElement|NewTail]) :-
RowElement \= cell(point(X,_),_),
replace_cell(X, Element, Tail, NewTail).
%match
replace_cell(X, Element, [cell(point(X,_),_)|Tail], [Element|Tail]).
This is the standard recursion you're probably used to. A goal is set, an answer is reached and Prolog starts stepping back through the calls made, filling in the variables we left open as it steps back. Then those filled variables become the output to the next returned call.
To then do it with multiple layers of lists, we just need to figure out which list we need to pass to the next, more specific call. In this matrix example, it's a square so all columns share an X and all rows share an Y coordinate. To figure out which row we need, we can feed the entire matrix into a simple predicate which checks the Y. Note that we aren't actually modifying the matrix yet, just identifying the row. This is mostly to keep the code readable.
%are there any rows left?
move_to_row(_, [], []).
%is element's Y equal to row Y?
move_to_row(Y, [Row|_], Row) :- Row = [cell(point(_,Y),_)|_].
%move to next row
move_to_row(Y,[_|Tail], Row) :- move_to_row(Y,Tail,Row).
After replacing the element in the row, since we have both the old and the new row we can identify the old row and reconstruct the matrix with the new row.
replaceElement(_,_,[],[]).
replaceElement(Replacable, Replacement, [Item|List], [Replacable|NewList] ) :-
Item \= Replacable,
replaceElement(Replacable, Replacement, List, NewList),
replaceElement(Replacable, Replacement, [Replacable|List], [Replacement|List] ) :-
!.
So effectively, the position in the list is kept by the order in which we step through the list on the way down, and then the new list is rebuilt on the way up.
For list [1,2,3], [Head|Tail] gives us Head = 1, Tail = [2,3]. If we then call [Head|Tail] again, it gives us Head = 2, Tail = [3]. On the way back, the exact opposite happens and the Head is appended to the front of the Tail. By visualizing each layer of lists as its own identifiable type and giving them their own identifier, it should be fairly simple to go through them efficiently irregardless of how many lists within lists you want to nest. The matrix is a 2d rectangle, but for example by having the coordinates within cell as a list and adding a Z axis it can fairly easily be turned into a cube or something even more complex with more than 3 dimensions.
I have an OrderedDict of lists, for example:
data = OrderedDict([('a', [3, 2, 1]]), ('b', [z, y, x])])
I would like to sort both lists by data['a']. The result would look like:
OrderedDict([('a', [1, 2, 3]]), ('b', [x, y, z])])
where the elements maintain relative index position across all lists.
I can do it by tracking the indices:
sorted_data = sorted([(t, i) for t, i in zip(data['a'],range(len(data['a'])))])
but that requires another loop to sort out the other column(s). This example is shortened - there are many more dictionary entries. Is there a more Pythonic way to do this, say with operator.itemgetter?
Thanks.
I'll take my own answer for now, until someone submits something more refined. This is my solution but seems clunky:
sortedData = sorted([(t, i) for t, i in zip(data['a'],range(len(data['a'])))])
sortedIndex = [i[1] for i in sortedData]
for key in data.keys():
data[key] = [ data[key][i] for i in sortedIndex]
I have a function that outputs names that fit a specific constraint. This function is fine.
But I need to use that function to make another function that turns the outputs of the former function into a list. Being a complete beginner with Prolog, I have no clue how to do this.
My problem is that I don't know how to iterate over the outputs to append it to an accumulator. The function which outputs names does so, then I press ";" or SPACE and it outputs the next answer until it's out of answers. I figure this means I have to make multiple calls to the function then append it. But I don't know how many times I need to call it, since I can't iterate over it like a list with [Head|Tail].
Here's what I have so far(although it's probably wrong):
%p1(L,X) determines if chemicals in List X are in any of the products and stores those products in L
p1(L,X) :- p1_helper(L,X,[]).
p1_helper(L,X,Acc) :- has_chemicals(A,X),append(Acc,[A],K),L=K, p1_helper(L,X,K).
function that outputs names with query has_chemicals(X,[List of Chemicals]).:
%has_chemicals(X,Is) determines if the chemicals in List Is are in the chemical list of X.
has_chemicals(X,Is) :- chemicals(X,Y), hc(Y,Is).
%hc(X,Y) determines if elements of Y are in elements of X.
hc(Y,[]).
hc(Y,[C|D]) :- isin(C,Y), hc(Y,D).
Any help is appreciated.
But I need to use that function to make another function that turns the outputs of the former function into a list. Being a complete beginner with Prolog, I have no clue how to do this.
findall(+Template, :Goal, -Bag):
Creates a list of the instantiations Template gets successively on backtracking over Goal and unifies the result with Bag.
For example, how to collect all odd numbers from 1 to 15:
odd( X ) :-
X rem 2 =:= 1.
We can get all that odds one-by-one.
?- between( 1, 15, X ), odd( X ).
X = 1 ;
X = 3 ;
X = 5 ;
X = 7 ;
X = 9 ;
X = 11 ;
X = 13 ;
X = 15.
And we can collect them into a list:
?- findall(X, (between( 1, 15, X ), odd( X )), List).
List = [1, 3, 5, 7, 9, 11, 13, 15].
I think you are looking for a way to capture the output of isin/2. Then you can use the builtin with_output_to/2, and combine it with findall/3, as suggested by other answers.
I encourage you to visit this page especially if you use swi-prolog.
There are 4 predicates that do what you want : findall/3, findall/4, bagof/3 and setof/3.
To summarize, here is the test predicate I'll be working with :
test(0, 3).
test(1, 3).
test(2, 5).
test(3, 4).
First, the simplest, findall/3 and findall/4 :
?- findall(C, test(X, C), Cs).
Cs = [3, 3, 5, 4].
?- findall(C, test(X, C), Cs, TailCs).
Cs = [3, 3, 5, 4|TailCs].
They just return all the alternatives, with duplicates, without sorting, without binding the other free variables, as a normal list for findall/3 and difference list for findall/4. both findalls predicates succeed when the list is empty.
Then, bagof. Basically, bagof/3 works as findall/3 but binds free variables. That means that the same query than above but with bagof/3 returns :
?- bagof(C, test(X, C), Cs).
X = 0,
Cs = [3] ;
X = 1,
Cs = [3] ;
X = 2,
Cs = [5] ;
X = 3,
Cs = [4].
By telling bagof/3 not to bind all the free variables, you obtain findall/3 :
?- bagof(C, X^test(X, C), Cs).
Cs = [3, 3, 5, 4].
Still you have to note that bagof/3 fails when the result is empty, where findall/3 doesn't.
Finally, setof/3. It's basically bagof/3 but with the results sorted and no duplicates :
?- setof(C, X^test(X, C), Cs).
Cs = [3, 4, 5].
In Mathematica I have a list:
x = {1,2,3,3,4,5,5,6}
How will I make a list with the duplicates? Like:
{3,5}
I have been looking at Lists as Sets, if there is something like Except[] for lists, so I could do:
unique = Union[x]
duplicates = MyExcept[x,unique]
(Of course, if the x would have more than two duplicates - say, {1,2,2,2,3,4,4}, there the output would be {2,2,4}, but additional Union[] would solve this.)
But there wasn't anything like that (if I did understand all the functions there well).
So, how to do that?
Lots of ways to do list extraction like this; here's the first thing that came to my mind:
Part[Select[Tally#x, Part[#, 2] > 1 &], All, 1]
Or, more readably in pieces:
Tally#x
Select[%, Part[#, 2] > 1 &]
Part[%, All, 1]
which gives, respectively,
{{1, 1}, {2, 1}, {3, 2}, {4, 1}, {5, 2}, {6, 1}}
{{3, 2}, {5, 2}}
{3, 5}
Perhaps you can think of a more efficient (in time or code space) way :)
By the way, if the list is unsorted then you need run Sort on it first before this will work.
Here's a way to do it in a single pass through the list:
collectDups[l_] := Block[{i}, i[n_]:= (i[n] = n; Unevaluated#Sequence[]); i /# l]
For example:
collectDups[{1, 1, 6, 1, 3, 4, 4, 5, 4, 4, 2, 2}] --> {1, 1, 4, 4, 4, 2}
If you want the list of unique duplicates -- {1, 4, 2} -- then wrap the above in DeleteDuplicates, which is another single pass through the list (Union is less efficient as it also sorts the result).
collectDups[l_] :=
DeleteDuplicates#Block[{i}, i[n_]:= (i[n] = n; Unevaluated#Sequence[]); i /# l]
Will Robertson's solution is probably better just because it's more straightforward, but I think if you wanted to eek out more speed, this should win. But if you cared about that, you wouldn't be programming in Mathematica! :)
Here are several faster variations of the Tally method.
f4 uses "tricks" given by Carl Woll and Oliver Ruebenkoenig on MathGroup.
f2 = Tally## /. {{_, 1} :> Sequence[], {a_, _} :> a} &;
f3 = Pick[#, Unitize[#2 - 1], 1] & ## Transpose#Tally## &;
f4 = # ~Extract~ SparseArray[Unitize[#2 - 1]]["NonzeroPositions"] & ## Transpose#Tally## &;
Speed comparison (f1 included for reference)
a = RandomInteger[100000, 25000];
f1 = Part[Select[Tally##, Part[#, 2] > 1 &], All, 1] &;
First#Timing#Do[##a, {50}] & /# {f1, f2, f3, f4, Tally}
SameQ ## (##a &) /# {f1, f2, f3, f4}
Out[]= {3.188, 1.296, 0.719, 0.375, 0.36}
Out[]= True
It is amazing to me that f4 has almost no overhead relative to a pure Tally!
Using a solution like dreeves, but only returning a single instance of each duplicated element, is a bit on the tricky side. One way of doing it is as follows:
collectDups1[l_] :=
Module[{i, j},
i[n_] := (i[n] := j[n]; Unevaluated#Sequence[]);
j[n_] := (j[n] = Unevaluated#Sequence[]; n);
i /# l];
This doesn't precisely match the output produced by Will Robertson's (IMO superior) solution, because elements will appear in the returned list in the order that it can be determined that they're duplicates. I'm not sure if it really can be done in a single pass, all the ways I can think of involve, in effect, at least two passes, although one might only be over the duplicated elements.
Here is a version of Robertson's answer that uses 100% "postfix notation" for function calls.
identifyDuplicates[list_List, test_:SameQ] :=
list //
Tally[#, test] & //
Select[#, #[[2]] > 1 &] & //
Map[#[[1]] &, #] &
Mathematica's // is similar to the dot for method calls in other languages. For instance, if this were written in C# / LINQ style, it would resemble
list.Tally(test).Where(x => x[2] > 1).Select(x => x[1])
Note that C#'s Where is like MMA's Select, and C#'s Select is like MMA's Map.
EDIT: added optional test function argument, defaulting to SameQ.
EDIT: here is a version that addresses my comment below & reports all the equivalents in a group given a projector function that produces a value such that elements of the list are considered equivalent if the value is equal. This essentially finds equivalence classes longer than a given size:
reportDuplicateClusters[list_List, projector_: (# &),
minimumClusterSize_: 2] :=
GatherBy[list, projector] //
Select[#, Length## >= minimumClusterSize &] &
Here is a sample that checks pairs of integers on their first elements, considering two pairs equivalent if their first elements are equal
reportDuplicateClusters[RandomInteger[10, {10, 2}], #[[1]] &]
This thread seems old, but I've had to solve this myself.
This is kind of crude, but does this do it?
Union[Select[Table[If[tt[[n]] == tt[[n + 1]], tt[[n]], ""], {n, Length[tt] - 1}], IntegerQ]]
Given a list A,
get the non-duplicate values in B
B = DeleteDuplicates[A]
get the duplicate values in C
C = Complement[A,B]
get the non-duplicate values from the duplicate list in D
D = DeleteDuplicates[C]
So for your example:
A = 1, 2, 2, 2, 3, 4, 4
B = 1, 2, 3, 4
C = 2, 2, 4
D = 2, 4
so your answer would be DeleteDuplicates[Complement[x,DeleteDuplicates[x]]] where x is your list. I don't know mathematica, so the syntax may or may not be perfect here. Just going by the docs on the page you linked to.
Another short possibility is
Last /# Select[Gather[x], Length[#] > 1 &]