I have this nested list:
list = [[1, 2, 3, 4],
[2, 7, 2, 1],
[3, 3, 7, 5],
[4, 4, 1, 7]]
And I'm trying to skip the first list of this nested list, and the first element of each list. I want it to become like this:
list = [[7, 2, 1],
[3, 7, 5],
[4, 1, 7]]
So far I have this:
% skip first list in list of lists
skip_first_list([_|Tail], Tail).
% attemping to skip first element in each of the lists
skip_first_list([[_ | HeadTail] | Tail], X) :-
skip_first_list(Tail, R),
append(R, [HeadTail], X).
Which does not produce the correct result:
?- skip_first_list([[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]], X).
X = [[2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]] ;
X = [[3, 3, 7, 5], [4, 4, 1, 7], [2, 3, 4]] ;
X = [[4, 4, 1, 7], [7, 2, 1], [2, 3, 4]] ;
X = [[3, 7, 5], [7, 2, 1], [2, 3, 4]] ;
false.
Whereas I'm after this answer:
X = [[7, 2, 1], [3, 7, 5], [4, 1, 7]]
My result so far seems to be showing I'm appending in a reverse/incorrect order, How can I fix this? I don't really understand what order Prolog evaluates expressions. Any any would be appreciated.
Well the specification is that you provide a list of lists and that:
the first sublist is ignored (not part of the output); and
that for the remaining sublists, all heads are ignored as well.
So we better split this into two predicates:
remove_heads/2, which removes the heads of all sublists; and
remove_upper_left/2 which remove the first sublist, and then uses the above predicate to pop the heads of the sublists.
We can perform remove_heads/2 for instance with recursion:
remove_heads([],[]).
remove_heads([[_|H]|T],[H|T2]) :-
remove_heads(T,T2).
finally our remove_upper_left/2 simply ignores the head of the list, and makes a call to remove_heads with the tail:
remove_upper_left([_|T],T2) :-
remove_heads(T,T2).
Or in full:
remove_heads([],[]).
remove_heads([[_|H]|T],[H|T2]) :-
remove_heads(T,T2).
remove_upper_left([_|T],T2) :-
remove_heads(T,T2).
This then produces:
?- remove_upper_left([[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]],X).
X = [[7, 2, 1], [3, 7, 5], [4, 1, 7]].
and works in the opposite direction as well:
?- remove_upper_left(X, [[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]]).
X = [_G1364, [_G1370, 1, 2, 3, 4], [_G1376, 2, 7, 2, 1], [_G1382, 3, 3, 7, 5], [_G1388, 4, 4, 1|...]].
So here it prepends a variable to every list, and prepends a variable (possibly a sublist) to the output.
Furthermore we have here two predicates at the price of one: we can also use remove_heads/2 in the future if we want to pop the heads of all the sublists in a list of lists.
Related
I want to write a predicate in Prolog, which creates a all possible segments of a given Size of a given List and returns the un-selected elements as a List.
My Code so far:
select_seg(List, Segment, Rest, Size ):-
select_seg(List, Segment, Rest, Size, Size).
select_seg(_,_,_,_, 0):- !.
select_seg(List, [Head_Segs|Tail_Segs],[Head_Rest|Tail_Rest], Size,Acc ):-
select(Head_Segs, List, Head_Rest),
Acc >= 0,
New_Acc is Acc - 1,
select_seg(Head_Rest, Tail_Segs, Tail_Rest, Size, New_Acc).
When I call this predicate with:
select_seg([1,2,3,4,5,6,7,8,9], Seg, R ,3 ).
It returns:
Seg = [1, 2, 3|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [4, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 4|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [3, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 5|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [3, 4, 6, 7, 8, 9]|_] ;
This is desired output, except that the list of remaining elements contain three lists for each element in the Segment the List of remaining elements, but should only contain the last one as following:
Seg = [1, 2, 3|_],
R = [4, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 4|_],
R = [3, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 5|_],
R = [3, 4, 6, 7, 8, 9]|_] ;
I tried everything, but I am not able to come up with the right solution.
It's combining select with a variant of select:
select_len_seg(Len, L, Seg, Rem) :-
length(Seg, Len),
select_len_seg_(Seg, L, L, Rem).
select_len_seg_([], _, R, R).
select_len_seg_([H|T], F, R, Rem) :-
% Preventing "duplicates" such as [3,2,1]
select_forward(H, F, F0),
select(H, R, R0),
select_len_seg_(T, F0, R0, Rem).
select_forward(E, [H|T], F) :-
select_forward_(T, H, E, F).
select_forward_(T, H, H, T).
select_forward_([H|T], _, E, F) :-
select_forward_(T, H, E, F).
Results in swi-prolog:
?- select_len_seg(3, [1,2,3,4,5,6,7,8,9], S, R).
S = [1, 2, 3],
R = [4, 5, 6, 7, 8, 9] ;
S = [1, 2, 4],
R = [3, 5, 6, 7, 8, 9] ;
...
S = [6, 7, 9],
R = [1, 2, 3, 4, 5, 8] ;
S = [6, 8, 9],
R = [1, 2, 3, 4, 5, 7] ;
S = [7, 8, 9],
R = [1, 2, 3, 4, 5, 6] ;
false.
I have some code that takes a given list of pairs of numbers and solves for chains of 7. However, it takes an obnoxious amount of time to solve for even one (well, i haven't solved for 1 yet and it has been a large amount of time). I was wondering if there was a better/more efficient way of coding this.
Here's what I did, with out the numbers in the list "L". (the list looks like such: L= [[1,2],[2,3],...])
length(L,LEN),
interval(N1,1,LEN),
interval(N2,1,LEN),
interval(N3,1,LEN),
interval(N4,1,LEN),
interval(N5,1,LEN),
interval(N6,1,LEN),
interval(N7,1,LEN),
nth1(N1,L,A),
nth1(N2,L,B),
nth1(N3,L,C),
nth1(N4,L,D),
nth1(N5,L,E),
nth1(N6,L,F),
nth1(N7,L,G),
nth1(2,A,A2),
nth1(1,B,B1),
A2 = B1,
nth1(2,B,B2),
nth1(1,C,C1),
B2 = C1,
nth1(2,C,C2),
nth1(1,D,D1),
C2 = D1,
nth1(2,D,D2),
nth1(1,E,E1),
D2 = E1,
nth1(2,E,E2),
nth1(1,F,F1),
E2 = F1,
nth1(2,F,F2),
nth1(1,G,G1),
F2 = G1,
nth1(2,G,G2),
nth1(1,A,A1),
G2 = A1,
R = (A,B,C,D,E,F,G).
If I understand your intention correctly, you can write this shorter as
use_module(library(clpfd)).
q(L,R) :-
[A,B,C,D,E,F,G] ins 1 .. 7,
R = [[A,B],[B,C],[C,D],[D,E],[E,F],[F,G],[G,A]],
permutation(L, R),
label([A,B,C,D,E,F,G]).
Example:
3 ?- q([[1,7],[2,3],[5,4],[3,1],[7,6],[6,5],[4,2]],X).
X = [[1, 7], [7, 6], [6, 5], [5, 4], [4, 2], [2, 3], [3, 1]] ;
X = [[2, 3], [3, 1], [1, 7], [7, 6], [6, 5], [5, 4], [4, 2]] ;
X = [[5, 4], [4, 2], [2, 3], [3, 1], [1, 7], [7, 6], [6, 5]] ;
X = [[3, 1], [1, 7], [7, 6], [6, 5], [5, 4], [4, 2], [2, 3]] ;
X = [[7, 6], [6, 5], [5, 4], [4, 2], [2, 3], [3, 1], [1, 7]] ;
X = [[6, 5], [5, 4], [4, 2], [2, 3], [3, 1], [1, 7], [7, 6]] ;
X = [[4, 2], [2, 3], [3, 1], [1, 7], [7, 6], [6, 5], [5, 4]] ;
false.
But your question is really unclear.
update: We can create the kind of lists we use above, of any length, with
vars(N, Vars):-
length(Vars, N).
pairs(Vars, N, Pairs):- % assuming vars(N, Vars)
N #> 0,
append(Vars,[A],[A|B]), % |B| = N
maplist( pair, Vars, B, Pairs).
pair( A, B, [A,B]).
Such that q/2 can be generalized as
gen_q(L,R) :-
length( L, N),
vars( N, Vars),
Vars ins 1 .. N,
pairs( Vars, N, R),
permutation(L, R),
label(Vars).
But computational feasibility of this for larger inputs is another matter entirely. The brute force of permutation/2 may have to be replaced with something more specific.
Also, the N results produced comprise a clear pattern; there's no need to re-enter the search to produce them all after the first one is found.
Why in the following example is appending to the big_l in the for loop changes also the last lists already added to the big_l?
l=[1,2,3,4,5]
big_l=[]
def f(ll):
x=ll.pop(0)
ll.append(x)
return ll
for i in range(4):
big_l.append(l)
print l,big_l
l=f(l)
It prints:
[1, 2, 3, 4, 5] - [[1, 2, 3, 4, 5]]
[2, 3, 4, 5, 1] - [[2, 3, 4, 5, 1], [2, 3, 4, 5, 1]]
[3, 4, 5, 1, 2] - [[3, 4, 5, 1, 2], [3, 4, 5, 1, 2], [3, 4, 5, 1, 2]]
[4, 5, 1, 2, 3] - [[4, 5, 1, 2, 3], [4, 5, 1, 2, 3], [4, 5, 1, 2, 3], [4, 5, 1, 2, 3]]
I have python lists like follows
>>>[[2, 0, 10], [2, 0, 11], [2, 1, 12], [2, 1, 13], [4, 3, 5], [4, 3, 7], [7, 6, 8], [7, 6, 10], [10, 9, 2], [10, 9, 11], [13, 14, 15]]
>>>[[0, 1, 3], [0, 1, 6], [3, 2, 0], [3, 2, 6], [3, 4, 5]]
I want to extract largest list set containing uncommon values. For example, for latter list, the largest independent set should be [[0, 1, 6], [3, 4, 5]], whereas for the former, it should be [[2, 0, 12], [4, 3, 5], [7, 6, 8], [10, 9, 11], [13, 14, 15]]. It may be similar with maximum independent set problem, but I have no idea about this as I know nothing about graphs. So any suggestion to solve this problem? Thanks in advance.
Is there any way to select the second, third (etc) value from a value in a list in Groovy? I'm still very new to programming in general and am just wondering if there is an easy way to do this.
For example, if I have the list
[1, 2, 3, 4, 5, 6]
I want to select the next two values after each value using a for loop:
for 1: (1, 2, 3)
for 2: (2, 3, 4)
...and so on.
Is that easily possible? Thanks in advance!
If you're using groovy 1.8.1 or later, you can use the take and drop methods:
def foo = [1, 2, 3, 4, 5, 6]
foo.size().times { i ->
println foo.drop(i).take(3)
}
This will result in
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
[5, 6]
[6]
If you want the iteration to stop at the last group of three, try something like this:
def foo = [1, 2, 3, 4, 5, 6]
if (foo.size() > 2) {
(foo.size() - 2).times { i ->
println foo.drop(i).take(3)
}
}
which gives
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
If you're not using Groovy 1.8.1+, then you can acheive a similar result by writing a function like so:
List split( List foo, int size ) {
(0..foo.size()-size).collect { foo[ it..it+size-1 ] }
}
Then, you can call this like:
split( [1, 2, 3, 4, 5, 6], 3 )
to print
[[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]