Dart - problem with multi-dimensional lists - list

I am programming in Dart and I need a multi-dimensional array to be filled with some data. But when I tried to run it, data at previous indexes were overwritten.
Here is my code:
List<List<String>> list = List.filled(4, List.filled(4, ""));
String toFill = "abcdefghijklmnop";
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
list[i][j] = toFill[i * 4 + j];
}
}
print(list);
I expected output of print() function to be
[[a, b, c, d], [e, f, g, h], [i, j, k, l], [m, n, o, p]]
but when I run it, it printed
[[m, n, o, p], [m, n, o, p], [m, n, o, p], [m, n, o, p]]
I don't know, why the last part is duplicating over to previous values.
I'd be glad for any help.
Thanks

I was able to solve this use List.generate which makes a new list from an iterable.
List<List<String>> list = List.generate(4, (int index) => List.generate(4, (int index) => ""));
Which gives me
> [[a, b, c, d], [e, f, g, h], [i, j, k, l], [m, n, o, p]]
This seems a little verbose, so there may be a shortcut to do the same thing.
Edit: Since you don't care about the index variable, you can shorten it somewhat but ignoring it:
List<List<String>> list = List.generate(4, (_) => List.generate(4, (_) => ""));

You could also combine the creating and filling the list:
import 'dart:math';
void main() {
String toFill = "abcdefghijklmnopqrstuvwxyz";
List<List<String>> list = List.generate(
(toFill.length/4).ceil(),
(i) => toFill.substring(i*4, min(toFill.length, (i+1)*4)).split(''),
);
print(list);
}
[[a, b, c, d], [e, f, g, h], [i, j, k, l], [m, n, o, p], [q, r, s, t], [u, v, w, x], [y, z]]
Which, if your string is always 16 characters long, can be simplified to:
void main() {
String toFill = "abcdefghijklmnop";
List<List<String>> list = List.generate(
4,
(i) => toFill.substring(i*4, (i+1)*4).split(''),
);
print(list);
}

Related

Splitting a list into two sublists with one having a predefined length

I'm new to Prolog and I have this code. I would like it to split a list into two lists or sublists where the first sublist/ list is of a predefined length and the other one contains the rest of the elements. Here's the code.
`
list_length([],0).
list_length([_|T],N):- list_length(T, N1), N is N1 + 1.
div(L, A, B, N) :-
append(A, B, L),
length(A, N),
length(B, N).
div(L, A, B, N) :-
append(A, B, L),
length(A, N),
N1 is N + 1,
length(B, N1).
div(L, A, B, N) :-
append(A, B, L),
length(A, N),
N1 is N - 1,
length(B, N1).
``
When I run my above code, it returns an error saying:
ERROR: Unknown procedure: (div)/4
ERROR: However, there are definitions for:
ERROR: (div)/3
false.
I would like the input to be this:
`?- div([44,55,23,86,49,94,30,77], L1, L2, 6).
L1 = [44,55,23,86,49,94]
L2 = [30,77]
Help me understand what I am doing wrong.
Help me understand what I am doing wrong.
You should be using length/2 and append/3, one after the other, like this:
div(L, A, B, N) :-
append(A, B, L),
length(A, N).
This is all.
Do not define your own length/2.
But you have not shown how you compile and evaluate your code. For example, I get:
?- [user].
|: div(L, A, B, N) :- append(A, B, L), length(A, N).
|: ^D% user://1 compiled 0.01 sec, 1 clauses
true.
?- div([a,b,c,d], A, B, 2).
A = [a, b],
B = [c, d] ;
false.
?- div([a,b,c,d], [X,Y], B, N).
X = a,
Y = b,
B = [c, d],
N = 2.
?- div([a,b,c,d], A, [X,Y,Z], N).
A = [a],
X = b,
Y = c,
Z = d,
N = 1 ;
false.
?- div([a,b], A, B, N).
A = [],
B = [a, b],
N = 0 ;
A = [a],
B = [b],
N = 1 ;
A = [a, b],
B = [],
N = 2 ;
false.
?- div(L, A, B, N).
L = B,
A = [],
N = 0 ;
L = [_A|B],
A = [_A],
N = 1 ;
L = [_A, _B|B],
A = [_A, _B],
N = 2 .
Since I made that mistake already, it is worth asking: Can you switch the order of append and length in the definition? What happens if you do?

Accessing elements inside parenthesis in Prolog

So i have this predicate letras_comuns(Lst_Pals, Letras_comuns) in which Lst_Pals is a list of like [[a,t,o],[a,c,o],[a,n,o]] and Letras_comuns is the a list with all the elements common in every word at a given index, e.g. [(1,a), (3,o)].
Example:
?- Lst_Pals = [[a,t,o], [a,c,o], [a,n,o], [a,l,o]],
letras_comuns(Lst_Pals, Letras_comuns).
Lst_Pals = [[a, t, o], [a, c, o], [a, n, o], [a, l, o]],
Letras_comuns = [(a, 1), (o, 3)].
So basically what this means is that all the words in Lst_pals have an a in the 1st index and an o in the 3rd/last index.
The problem is that i want to access to the elements inside the parenthesis and i know if put (X,Y) = (a,1) i can access its elements, the thing is that this only works for 1 and i want to access to all of them, so anyone can tell me how because i'm clueless on how to do this.
You can define
p( (X,Y), X, Y ).
then use it:
?- p( (a,1), A, I ).
A = a,
I = 1.
or
?- maplist( p, [(a, 1), (o, 3)], AS, IS).
AS = [a, o],
IS = [1, 3].

How to swap three by three elements in a prolog list?

I'm doing an exercise in Prolog and I'm stuck.
I need to swap three adjacent items in a list with another three elements.
That is:
| ?- swap([c,g,g,a,t,t,g,c,a,a], X).
X = [a,t,t,c,g,g,g,c,a,a]
X = [g,c,a,a,t,t,c,g,g,a]
X = [c,g,g,g,c,a,a,t,t,a]
X = [c,a,a,a,t,t,g,c,g,g]
.
.
.
This is what I have so far:
swap([H1, H2, H3, H4, H5, H6|T1], X) :-
X = [H4, H5, H6, H1, H2, H3|T1];
swap([H2, H3, H4, H5, H6|T1], X);
swap([H1, H2, H3, H4, H5|T1], X).
And the output for this is:
| ?- swap([c,g,g,a,t,t,g,c,a,a], X).
X = [a, t, t, c, g, g, g, c, a, a] ;
X = [t, t, g, g, g, a, c, a, a] ;
X = [t, g, c, g, a, t, a, a] ;
X = [g, c, a, a, t, t, a] ;
X = [c, a, a, t, t, g] ;
X = [c, a, a, a, t, t] ;
X = [g, c, a, g, a, t, a] ;
X = [c, a, a, a, t, g] ;
X = [c, a, a, g, a, t] ;
X = [t, g, c, g, g, a, a, a] ;
X = [g, c, a, g, a, t, a] ;
X = [c, a, a, a, t, g] ;
X = [c, a, a, g, a, t] ;
X = [g, c, a, g, g, a, a] ;
X = [c, a, a, g, a, g] ;
X = [c, a, a, g, g, a] ;
X = [t, t, g, c, g, g, c, a, a] ;
X = [t, g, c, g, g, t, a, a] ;
X = [g, c, a, g, t, t, a] ;
X = [c, a, a, t, t, g] ;
X = [c, a, a, g, t, t] ;
X = [g, c, a, g, g, t, a] ;
X = [c, a, a, g, t, g] ;
X = [c, a, a, g, g, t] ;
X = [t, g, c, c, g, g, a, a] ;
X = [g, c, a, g, g, t, a] ;
X = [c, a, a, g, t, g] ;
X = [c, a, a, g, g, t] ;
X = [g, c, a, c, g, g, a] ;
X = [c, a, a, g, g, g] ;
X = [c, a, a, c, g, g] ;
false.
The only problem that I have is that with every recursion I lose some part of the list and I don't know how to put it back.
It seems you are interested in describing RNA-sequences. Triples, that sounds much like anticodons. To make those sequences more readable, use:
:- set_prolog_flag(double_quotes, chars).
which permits you to write "attac" in place of [a,t,t,a,c]. See this how to get also compact answers.
Now for the swap. The easiest way is to first sketch what you want:
... Triple1 ... Triple2 ... is the OldSequence
... Triple2 ... Triple1 ... is the NewSequence
Where the ... are the same for both sequences. All of this can be readily translated using DCGs.
tripleswap(OldSequence, NewSequence) :-
dif(T1,T2),
phrase( ( seq(A), triple(T1), seq(B), triple(T2), seq(C) ), OldSequence),
phrase( ( seq(A), triple(T2), seq(B), triple(T1), seq(C) ), NewSequence).
seq([]) --> [].
seq([B|Bs]) --> [B], seq(Bs).
triple([A,B,C]) --> [A,B,C].
Whenever you distrust a DCG-definition, just try it out with phrase/2. Like
?- phrase(triple(T1), Bs).
T1 = Bs, Bs = [_A,_B,_C].
The non-terminal triple//1 describes a sequence of 3 elements (presumably nucleotides).
seq//1 is an arbitrarily long sequence.
There are solutions with better termination conditions, but they are less readable and often require certain assumptions that are difficult to maintain in the general case. Here is such a simple improvement:
samelength([], []).
samelength([_|Xs], [_|Ys]) :-
samelength(Xs, Ys).
and add samelength(OldSequence, NewSeqence) as the first goal. Now, tripleswap/2 terminates iff samelength/2 terminates. So one of the arguments should be a list of fixed length.
Also note that I think that "cccccc" has no swap. That's why I added dif(T1,T2).
?- tripleswap("cggattgcaa", Bs).
Bs = "attcgggcaa"
; Bs = "ttgacggcaa"
; Bs = "tgcatcggaa"
; Bs = "gcaattcgga"
; Bs = "caaattgcgg"
; Bs = "cttgggacaa"
; Bs = "ctgctggaaa"
; Bs = "cgcattggaa"
; Bs = "ccaattggga"
; Bs = "cgtgcgataa"
; Bs = "cggcatgata"
; Bs = "cgcaatggat"
; Bs = "cgggcaatta"
; Bs = "cggcaagatt"
; Bs = "cggacaattg"
; false.
BTW, dcgs are used in Molecular Biology since the 1980s. Start with
David B. Searls, Investigating the Linguistics of DNA with Definite Clause Grammars, NACLP 1989
and other work by the same author as well as Ross Overbeek around that time. All of this happened in the dawn of the Human Genome Project.
Basically this can be split into two subproblems:
first take a sequence of three elements; and
take another sequence of three elements and produce a list where we swapped these.
We can thus implement the two problems as follows:
swap(L, X) :-
swap1(L, S1, S2, T, X, Q),
swap2(T, S1, S2, Q).
where L is the list where we need to perform the swaps, X the list that is unified with the results, S1 and S2 the sequences that we select to swap, T the remaining elements after the first selection, and Q the part after the second sequence of the list to swap.
The first swap1 can thus be implemented as:
swap1([A1, A2, A3|T], [A1, A2, A3], [B1, B2, B3], T, [B1, B2, B3|Q], Q).
swap1([A1|T], A, B, R, [A1|Rest], S) :-
swap1(T, A, B, R, Rest, S).
For the given sample list, this will thus yield:
?- swap1([c,g,g,a,t,t,g,c,a,a], A, [B1, B2, B3], T, X, R).
A = [c, g, g],
T = [a, t, t, g, c, a, a],
X = [B1, B2, B3|R] ;
A = [g, g, a],
T = [t, t, g, c, a, a],
X = [c, B1, B2, B3|R] ;
A = [g, a, t],
T = [t, g, c, a, a],
X = [c, g, B1, B2, B3|R] ;
A = [a, t, t],
T = [g, c, a, a],
X = [c, g, g, B1, B2, B3|R] ;
A = [t, t, g],
T = [c, a, a],
X = [c, g, g, a, B1, B2, B3|R] ;
A = [t, g, c],
T = [a, a],
X = [c, g, g, a, t, B1, B2, B3|R] ;
A = [g, c, a],
T = [a],
X = [c, g, g, a, t, t, B1, B2, B3|...] ;
A = [c, a, a],
T = [],
X = [c, g, g, a, t, t, g, B1, B2|...] ;
false.
Here it thus proposes eight ways to pick three adjacent sequences that can be used to swap.
Then the second swap need to find three adjacent elements in the remaining lists to swap, and put the ones that have been picked by swap1/6 at the places where it picks elements from, like:
swap2([B1,B2,B3|R], [A1,A2,A3], [B1, B2, B3], [A1,A2,A3|R]).
swap2([B1|R], As, Bs, [B1|T]) :-
swap2(R, As, Bs, T).
For the given sample data, this thus gives us:
?- swap([c,g,g,a,t,t,g,c,a,a], X).
X = [a, t, t, c, g, g, g, c, a, a] ;
X = [t, t, g, a, c, g, g, c, a, a] ;
X = [t, g, c, a, t, c, g, g, a, a] ;
X = [g, c, a, a, t, t, c, g, g, a] ;
X = [c, a, a, a, t, t, g, c, g, g] ;
X = [c, t, t, g, g, g, a, c, a, a] ;
X = [c, t, g, c, t, g, g, a, a, a] ;
X = [c, g, c, a, t, t, g, g, a, a] ;
X = [c, c, a, a, t, t, g, g, g, a] ;
X = [c, g, t, g, c, g, a, t, a, a] ;
X = [c, g, g, c, a, t, g, a, t, a] ;
X = [c, g, c, a, a, t, g, g, a, t] ;
X = [c, g, g, g, c, a, a, t, t, a] ;
X = [c, g, g, c, a, a, g, a, t, t] ;
X = [c, g, g, a, c, a, a, t, t, g] ;
false.
Here the places that are swapped are written in boldface.
I think permutation/2 will help:
swap(Es,Sw) :- triples(Es,Ts),permutation(Ts,Sw0),append(Sw0,Sw).
triples([A,B,C|Es],[[A,B,C]|Ts]) :- !, triples(Es,Ts).
triples([],[]) :- !.
triples(R,[R]).
yields
?- swap([c,g,g, a,t,t, g,c,a], X).
X = [c, g, g, a, t, t, g, c, a] ;
X = [c, g, g, g, c, a, a, t, t] ;
X = [a, t, t, c, g, g, g, c, a] ;
X = [a, t, t, g, c, a, c, g, g] ;
X = [g, c, a, c, g, g, a, t, t] ;
X = [g, c, a, a, t, t, c, g, g] ;
false.
note: triples/2 allows for not triple data in tail, but you can drop this (maybe unwanted) feature just deleting the last clause:
triples(R,[R]). % drop this
Then the cuts become useless, just drop drop them:
triples([],[]). % just for style in this case, move to first clause
triples([A,B,C|Es],[[A,B,C]|Ts]) :- triples(Es,Ts).

Using Prolog to process a list

I have a problem in Prolog.
Consider a list where each element is referring to a position/location in the same list.
I want to write a program which returns true if I start with the same location that I end in. For example:
If I give it find-s([3,2,0,1],0)
It starts with 0 index which contains 3
then goes to the 3 index which contains 1
then the 1 index to find 2
finally to index 2 which contains 0 !
so it returns true in this case
I tried this but it didn't work
position([Head1| Tail1], Var1) :-
( Head1 == Var1,
Tail1 == Var1 ->
true
).
this should work
find_s(L, S) :- nth0(S, L, I), find_s(L, I, S).
find_s(_, S, S).
find_s(L, I, S) :- nth0(I, L, J), find_s(L, J, S).
but I think it could easily loop. So, instead of nth0/3, let's use nth0/4, after this consideration:
?- nth0(2,[a,b,c,d],X,Y).
X = c,
Y = [a, b, d].
?- nth0(2,L,$X,$Y).
L = [a, b, c, d].
for sake of readability, let's introduce a replace_nth0/4
replace_nth0(P, L, E, LrepE) :-
nth0(P, L, E, L_Without_E),
nth0(P, LrepE, -1, L_Without_E).
and then
find_s(L, S) :- nth0(S, L, I), find_s(L, I, S).
find_s(_, S, S).
find_s(L, I, S) :- I >= 0, replace_nth0(I, L, J, L_rep), find_s(L_rep, J, S).

erlang list manipulation

I have a list of tuples:
L = [{1, [a, b, c]}, {2, [d, e, f]}, {3, [[h, i, j], [k, l, m]]}]
this is what I have
lists:map(fun({_, B}-> B end, L).
the output is
[[a, b, c], [d, e, f], [[h, i, j], [k, l, m]]]
what I want is:
[[a, b, c], [d, e, f], [h, i, j], [k, l, m]]
it seems a pretty easy problem, but I can't figure out how to do it.
Please help!
Let's see...
1> L = [{1, [a, b, c]}, {2, [d, e, f]}, {3, [[h, i, j], [k, l, m]]}].
[{1,[a,b,c]},{2,[d,e,f]},{3,[[h,i,j],[k,l,m]]}]
Trivial and straightforward, but not tail-recursive:
2> lists:foldr(fun ({_,[X|_]=E},A) when is_list(X) -> lists:append(A,E);
({_,E},A) -> [E|A] end,
[], L).
[[a,b,c],[d,e,f],[h,i,j],[k,l,m]]
Not being tail-recursive is not very nice, though, but...
3> lists:reverse(lists:foldl(fun ({_,[X|_]=E},A) when is_list(X) ->
lists:reverse(E,A);
({_,E},A) -> [E|A] end,
[], L)).
[[a,b,c],[d,e,f],[h,i,j],[k,l,m]]
...the tail-recursive version also works (thanks to Zed for pointing out lists:reverse/2).
For your specific example case, you can define the following function:
group3([], Acc) ->
Acc;
group3([A,B,C|Tl], Acc) ->
group3(Tl, [[A,B,C]] ++ Acc).
group3(L) ->
lists:reverse(group3(L, [])).
and invoke it like this:
group3(lists:flatten(lists:map(fun({_, B}) -> B end, L))).
Hopefully that's enough to give you a general strategy.
-module(z).
-export([do/1]).
do([{_,[X|_] = L}|Tl]) when is_list(X) -> L ++ do(Tl);
do([{_, L} |Tl]) -> [L|do(Tl)];
do([]) -> [].
test:
1> z:do(L).
[[a,b,c],[d,e,f],[h,i,j],[k,l,m]]