I am trying to create a simple Algorithm in Dart but I think the programming language doesn't matter it is more about the Algorithm:
I am trying to make 2 lists of pairs of numbers depending on "row" and "column" for example:
col_1
col_2
1
2
3
4
5
6
7
8
9
10
=> I need a Algorithm that makes me 2 lists of numbers:
first list: 2,3,6,7,10...
second list: 4,5,8,9...
But this must also work when the "columns" change like that:
col_1
col_2
col_3
1
2
3
4
5
6
7
8
9
this time the first list must be:
3,4,9...
the second list:
6,7 ...
anyone has an Idea on how I could achieve this with a simple calculation? or algorithm depending on the "Maximum" amount of numbers?
You're probably looking for the modulo operator %
Directly, it can create a repeating series based upon the remainder of dividing by the value
For example, you could place your values into the Nth list in a list of lists (whew)
>>> cols = [[],[],[]]
>>> for x in range(12):
... cols[x % 3].append(x)
...
>>> cols
[[0, 3, 6, 9], [1, 4, 7, 10], [2, 5, 8, 11]]
0%5 --> 0
1%5 --> 1
...
11%5 --> 1
To massage values when you have (for example) some increment of 1, you can do a little math
>>> for x in range(12):
... print("x={} is in column {}".format(x + 1, (x % 3) + 1 ))
...
x=1 is in column 1
x=2 is in column 2
x=3 is in column 3
x=4 is in column 1
x=5 is in column 2
x=6 is in column 3
x=7 is in column 1
x=8 is in column 2
x=9 is in column 3
x=10 is in column 1
x=11 is in column 2
x=12 is in column 3
Note you may need to do some extra work to either
know how many values you need to fill all the columns
count and stop when you have enough rows
Examples are in Python because I'm most familiar with it
Note that work like [[],[],[]] should largely be avoided if a better collection is available (perhaps a dict of lists with column-name keys or Pandas DataFrame), but it makes for a good illustration
With a little discussion, https://oeis.org/A042964 seems like the solution, which suggests the following for testing entries for set membership
binomial(m+2, m) mod 2 = 0
in Python, this could be
>>> from scipy.special import binom # 3rd party math library
>>> for m in range(1, 15):
... print("{} belongs in list {}".format(m, 1 if binom(m+2, m) % 2 == 0 else 2))
...
1 belongs in list 2
2 belongs in list 1
3 belongs in list 1
4 belongs in list 2
5 belongs in list 2
6 belongs in list 1
7 belongs in list 1
8 belongs in list 2
9 belongs in list 2
10 belongs in list 1
11 belongs in list 1
12 belongs in list 2
13 belongs in list 2
14 belongs in list 1
If only the first list is desired, entries can be directly generated by the formula a(n)=2*n+2-n%2 (refer to PROG on OEIS page), rather than testing values for membership
>>> a = lambda n: 2*n+2-n%2
>>> [a(n) for n in range(10)]
[2, 3, 6, 7, 10, 11, 14, 15, 18, 19]
Related
I'd like to take a single array lets say 3x5 as follows
1 3 5
1 3 5
2 8 6
4 5 7
4 5 8
and write a code that will create a new array that adds the third column together with the previous number if the numbers in the first and second columns equal the numbers in the row below it.
since the first two values in row 1 and 2, then add the third elements in row 1 and 2 together
so the output from the array above should look like this
1 3 10
2 8 6
4 5 15
The function accumarray(subs,val) accumulate elements of vector val using the subscripts subs. So we can use this function to sum the elements in the third column having the same value in the first and second column. We can use unique(...,'rows') to determine which pairs of value are unique.
%Example data
A = [1 3 5,
1 3 5,
2 3 6,
4 5 7,
4 5 7]
%Get the unique pair of value based on the first two column (uni) and the associated index.
[uni,~,sub] = unique(A(:,1:2),'rows');
%Create the result using accumarray.
R = [uni, accumarray(sub,A(:,3))]
If the orders matters the script would be a little bit more complex:
%Get the unique pair of value based on the first two column (uni) and the associated index.
[uni,~,sub] = unique(A(:,1:2),'rows');
%Locate the consecutive similar row with this small tricks
dsub = diff([0;sub])~=0;
%Create the adjusted index
subo = cumsum(dsub);
%Create the new array
R = [uni(sub(dsub),:), accumarray(subo,A(:,3))]
Or you can get an identical result with a for loop:
R = A(1,:)
for ii = 2:length(A)
if all(A(ii-1,1:2)==A(ii,1:2))
R(end,3) = R(end,3)+A(ii,3)
else
R(end+1,:) = A(ii,:)
end
end
Benchmark:
With an array A of size 100000x3 on the mathworks live editor:
The for loop take about 5.5s (no pre-allocation, so it's pretty slow)
The vectorized method take about 0.012s
this is a paragraph from data structure book, by Narasimha Karumanchi (disjoint set ADT)
fast find implementation(quick find)
this method uses an array, where the array contains the set name for each element.
In this representation to perform union(a,b)[assuming that a, is in set i and b is in set j] we need to scan the complete array and change all i to j. this take O(n).
my question 1
if find operation takes O(1) then why scan complete array and change all i to j ,only two of them need to change , so how it is O(n)
============
(book 8.8 section)
using an array which stores the parent of each element instead of using root as its set name, solve union O(n)
my 2. question
how does it solve issue using parent?
And how both root and parent approaches gives us skew tree?
Consider that you have 8 elements in 2 sets, where the set identifiers are 1 and 2 (so i = 1 and j = 2 in your description).
Assume that 4 elements are in set 1 (elements 0, 1, 3, 7) and 4 elements are in set 2 (elements 2, 4, 5, 6).
Quick find implementation would represent this array as:
[ 1, 1, 2, 1, 2, 2, 2, 1 ]
And as the following representation (both elements 1 and 2 have self-loops):
1 2
/ | \ / | \
0 3 7 4 5 6
If you perform union(1, 2) and only update the set identifier (let’s assume that we are updating the elements in set 2 to point to set 1), then you would have an array such as:
[ 1, 1, 1, 1, 2, 2, 2, 1 ]
If you perform find(2) you get as a result the identifier 1, which is correct.
But if you perform find(4) you get as a result the identifier 2, which is incorrect because element 4 now belongs to set 1.
So you have to scan the complete array (and therefore the operation has time complexity O(n)) to update the identifiers, to have the following array as a result of the union operation:
[ 1, 1, 1, 1, 1, 1, 1, 1 ]
And the following representation (with 1 having a self-loop)
1
/ / | | \ \ \
0 2 3 4 5 6 7
As I'm sure you will see later in the book, there are more efficient implementations of the union-find data structure, which are based on union by rank and path compression.
The question is:
Given an unsorted array, sort it in such a way that the first element is the largest, the second element is the smallest, the third element is the second largest, etc.
Follow up: Can you do it without using extra space?
Example:
[2, 4, 3, 5, 1] -> [5, 1, 4, 2, 3]
I want to be able to sort the array without using extra space. What is the most efficient solution? I can only think of an O(n2) solution that loops through the array to find the next largest and next smallest elements. Is there a more efficient solution?
I've looked at the related questions Sorting an array with alternate smallest and largest values and Sorting an array with alternate smallest-largest values but the answers didn't help with my question.
precondition : using deque.
1.sorting the array.
loop)
2.pop_back(array) -> insert that element in i*2 position.
example) 1, 2, 3, 4, 5, 6, 7
a) 7 (insert to 0) -> 1 2 3 4 5 6 => 7 1 2 3 4 5 6
b) 6 (insert to 2) -> 7 1 2 3 4 5 => 7 1 6 2 3 4 5
c) 5 (insert to 4) -> 7 1 6 2 3 4 => 7 1 6 2 5 3 4 (finished)
Its complexity maybe O(nlog(n)) + O(n/2)
I wish to locate the first position of each unique number from a vector but without a for loop:
e.g
a=[1 1 2 2 3 4 2 1 3 4];
and I can obtain the unique number by having:
uniq=unique(a);
where uniq = [1 2 3 4]
What I want is to obtain each number's first appearance location, any ideas????
first_pos = [1 3 5 6]
where 1 is firstly appear in position 1, 4 is firstly appear in the sixth position from the vector
ALSO, what about the position of the second appearance??
second_pos = [2 4 9 10]
Thank you very much
Use the second output of unique, and use the 'first' option:
>> A = [1 1 2 2 3 4 2 1 3 4];
>> [a,b] = unique(A, 'first')
a =
1 2 3 4 %// the unique values
b =
1 3 5 6 %// the first indices where these values occur
To find the locations of the second occurrences,
%// replace first occurrences with some random number
R = rand;
%// and do the same as before
A(b) = R;
[a2,b2] = unique(A, 'first');
%// Our random number is NOT part of original vector
b2(a2==R)=[];
a2(a2==R)=[];
with this:
b2 =
2 4 9 10
Note that there will have to be at least 2 occurrences of each number in the vector A if the sizes of b and b2 are to agree (this was not the case before your edit).
I have two Matlab arrays A(containing groups of numbers) and B(containing values that belong to the groups in A), there are repeats in array A
A = [1 1 1 2 2 3 4 4 4 4 4]
B = [1 2 3 3 5 4 4 1 6 7 8]
Now i would like to get the following two maps:
C = ['1': {1,2,3}, '2': {3,5}, '3':{4}, '4':{1,6,7,8}]
where C gives a map with the group number as index and related values in that particular group.
D = ['1':{2,4},'2':{1},'3':{4},'4':{1}]
Where D gives a map with the group number from A as index. The values are the group numbers from A for which there are repeated values in B for that particular sub group.
What is the most efficient way of dealing with this problem? Are maps a good data structure to store this kind of data. I know the first one can be dealt with a for loop which i would like to avoid.
I don't understand how you get to D.
For C, you can use accumarray:
C = accumarray(A,B,[],#(x){x})
C{1} is [1 2 3]