Minimum sum of all elements in an array called array cost - arrays

Given an array [2,4,6,7]. We need to choose one number x. Over iterating entire array we need to assign the new values a[i]=a[i]/x.
In the above scenario they choose 2.
The result array is [1,2,3,7]
The array cost is 1+2+3+7=13.
How can we choose an element randomly?

There is a module in python called
random and that module has a function random.choice(<array>)
so the code would be :
array = [2, 4, 6, 7]
x = random.choice(array)
for i in range(len(array))
array[i] /= x

Related

Count elements in 1st array less than or equal than elements in 2nd array python

I have an array Aof 21381120 elements ranking from [0,1]. I need to construct a new array B in which the element i contains the number of elements in A less than or equal than A[i].
My attempt:
A = np.random.random(10000) # for reproducibility
g = np.sort(A)
B = [np.sum(g<=element) for element in A]
I am still using a for loop, taking too much time. Since I have to do this several times I was wondering if exists a better way to do it.
EDIT
I gave an example of the array A for reproducibility. This does what is expected to. But I need it to be faster (for arrays having 2e9 elements).
For instance if:
A = [0.1,0.01,0.3,0.5,1]
I expect the output to be
B = [2, 1, 3, 4, 5]
You could use binary search to speed up searching in a sorted array. Binary search in numpy.
A = np.random.rand(10000) # for reproducibility
g = np.sort(A)
B = [np.searchsorted(g, element) for element in A]
Looks like sorting is the way to go because in a sorted array A, the number of elements less than or equal to A[i] is almost i + 1.
However, if an element is repeated, you'll have to look at the nearest element that's to the right of A[i]:
A = [1,2,3,4,4,4,5,6]
^^^^^ A[3] == A[4] == A[5]
Here, the number of elements <= A[3] is 3 + <number of repeated 4's>. Maybe you could roll your own sorting algorithm that would keep track of such repetitions. Or count the repetitions before sorting the array.
Then the final formula would be:
N(<= A[k]) = k + <number of elements equal to A[k]>
So the speed of your code would mainly depend on the speed of the sorting algorithm.

How do I to lose the results of running python in the form of an array (ex: array ([1, 2, ..., 6, 7, 8])

example array :
[array([0.84312789, 0.75129959, 0.88778234, ..., 0.96588262, 0.98853215,
0.52034823])]
How do I know the value of (...) in the array list ?
thank you.
You are creating a list with an array in it, so your array is accessible with [0].
You can access elements in an array the same way you access list elements. You also have to supply a character code to the array module which describes the type of elements in the array.
example
from array import array
# 'd' describes double
x = array('d', [0.84312789, 0.75129959, 0.88778234, 0.96588262, 0.98853215, 0.52034823])
print(x[0][0])
prints
0.84312789

How to initialize a particular numpy array element value with a set of elements?

I have a code in which I want to create a multidimensional array of numpy with each element being another array of 3 elements of row vector here is how it looks:
a1=np.ndarray([4,4])
for i in range(4):
for j in range(4):
a1[i,j]=[2,2,2]
Now when I try to do so, I get an error:
ValueError: setting an array element with a sequence.
Please tell me where I went wrong.
Basically, my aim is to create a numpy ndarray( and not asarray or array) like this:
This is just a rough example of what I want to do.
[[1,1,1],[2,2,2],[3,3,3]
[4,4,4],[5,5,5],[6,6,6]
[1,2,3],[4,5,6],[1,2,4]]
The 3 element vector at every i, j location forms a third dimension. Thus the shape of the array should be [4, 4, 3] - the third dimension contains 3 elements.
a1 = np.ndarray([4, 4, 3])
...
your final array will have (4,4,3) shape. so you must reserve this room :
a1=np.empty((4,4,3),dtype=int)
# or np.ndarray((4,4,3),int)
for i in range(4):
for j in range(4):
a1[i,j]=[i,j,i+j] # for exemple

How to pick elements in fixed interval in an array (python)

Given array=[1, 2, 3, 4, 5, 6]
I want to choose the 0-th 2-nd, 4-th index value to build a new array
array1=[1, 3, 5]
Could someone show me how to do using python? Thanks~
If it is just 0, 2, and 4, you can use operator.itemgetter():
from operator import itemgetter
array1 = itemgetter(0, 2, 4)(array)
That will be a tuple. If it must be a list, convert it:
array1 = list(itemgetter(0, 2, 4)(array))
If the point is to get the even numbered indices, use slicing:
array1 = array[::2]
Whichever you are looking for, you could use a list comprehension:
array1 = [array[i] for i in (0, 2, 4)]
or
array1 = [array[i] for i in xrange(0, len(array), 2)]
You can try something like this. In python the nth term of a list has index (n-1). Suppose the first element you want is 2, which happens to be the element 1 of array. Just save the first element index in a variable. Append it to the new list array1 and increase the index by 2. Continue doing this until the list array is exhausted.
from numpy import*
array=[1,2,3,4,5,6]
array1=[]
term=1
while term<len(array): # if the array length is 6 then it will have upto element 5.
array1.append(array[term])
term=term+2 # 2 is the gap between elements. You can replace it with your required step size.

Number of Distinct Subarrays

I want to find an algorithm to count the number of distinct subarrays of an array.
For example, in the case of A = [1,2,1,2],
the number of distinct subarrays is 7:
{ [1] , [2] , [1,2] , [2,1] , [1,2,1] , [2,1,2], [1,2,1,2]}
and in the case of B = [1,1,1], the number of distinct subarrays is 3:
{ [1] , [1,1] , [1,1,1] }
A sub-array is a contiguous subsequence, or slice, of an array. Distinct means different contents; for example:
[1] from A[0:1] and [1] from A[2:3] are not distinct.
and similarly:
B[0:1], B[1:2], B[2:3] are not distinct.
Construct suffix tree for this array. Then add together lengths of all edges in this tree.
Time needed to construct suffix tree is O(n) with proper algorithm (Ukkonen's or McCreight's algorithms). Time needed to traverse the tree and add together lengths is also O(n).
Edit: I think about how to reduce iteration/comparison number.
I foud a way to do it: if you retrieve a sub-array of size n, then each sub-arrays of size inferior to n will already be added.
Here is the code updated.
List<Integer> A = new ArrayList<Integer>();
A.add(1);
A.add(2);
A.add(1);
A.add(2);
System.out.println("global list to study: " + A);
//global list
List<List<Integer>> listOfUniqueList = new ArrayList<List<Integer>>();
// iterate on 1st position in list, start at 0
for (int initialPos=0; initialPos<A.size(); initialPos++) {
// iterate on liste size, start on full list and then decrease size
for (int currentListSize=A.size()-initialPos; currentListSize>0; currentListSize--) {
//initialize current list.
List<Integer> currentList = new ArrayList<Integer>();
// iterate on each (corresponding) int of global list
for ( int i = 0; i<currentListSize; i++) {
currentList.add(A.get(initialPos+i));
}
// insure unicity
if (!listOfUniqueList.contains(currentList)){
listOfUniqueList.add(currentList);
} else {
continue;
}
}
}
System.out.println("list retrieved: " + listOfUniqueList);
System.out.println("size of list retrieved: " + listOfUniqueList.size());
global list to study: [1, 2, 1, 2]
list retrieved: [[1, 2, 1, 2], [1, 2, 1], [1, 2], [1], [2, 1, 2], [2, 1], [2]]
size of list retrieved: 7
With a list containing the same patern many time the number of iteration and comparison will be quite low.
For your example [1, 2, 1, 2], the line if (!listOfUniqueList.contains(currentList)){ is executed 10 times. It only raise to 36 for the input [1, 2, 1, 2, 1, 2, 1, 2] that contains 15 different sub-arrays.
You could trivially make a set of the subsequences and count them, but i'm not certain it is the most efficient way, as it is O(n^2).
in python that would be something like :
subs = [tuple(A[i:j]) for i in range(0, len(A)) for j in range(i + 1, len(A) + 1)]
uniqSubs = set(subs)
which gives you :
set([(1, 2), (1, 2, 1), (1,), (1, 2, 1, 2), (2,), (2, 1), (2, 1, 2)])
The double loop in the comprehension clearly states the O(n²) complexity.
Edit
Apparently there are some discussion about the complexity. Creation of subs is O(n^2) as there are n^2 items.
Creating a set from a list is O(m) where m is the size of the list, m being n^2 in this case, as adding to a set is amortized O(1).
The overall is therefore O(n^2).
Right my first answer was a bit of a blonde moment.
I guess the answer would be to generate them all and then remove duplicates. Or if you are using a language like Java with a set object make all the arrays and add them to a set of int[]. Sets only contain one instance of each element and automatically remove duplicates so you can just get the size of the set at the end
I can think of 2 ways...
first is compute some sort of hash then add to a set.
if on adding your hashes are the same is an existing array... then do a verbose comparison... and log it so that you know your hash algorithm isn't good enough...
The second is to use some sort of probable match and then drill down from there...
if number of elements is same and the total of the elements added together is the same, then check verbosely.
Create an array of pair where each pair store the value of the element of subarray and its index.
pair[i] = (A[i],i);
Sort the pair in increasing order of A[i] and then decreasing order of i.
Consider example A = [1,3,6,3,6,3,1,3];
pair array after sorting will be pair = [(1,6),(1,0),(3,7),(3,5),(3,3),(3,1),(6,4),(6,2)]
pair[0] has element of index 6. From index 6 we can have two sub-arrays [1] and [1,3]. So ANS = 2;
Now take each consecutive pair one by one.
Taking pair[0] and pair[1],
pair[1] has index 0. We can have 8 sub-arrays beginning from index 0. But two subarrays [1] and [1,3] are already counted. So to remove them, we need to compare longest common prefix of sub-array for pair[0] and pair[1]. So longest common prefix length for indices beginning from 0 and 6 is 2 i.e [1,3].
So now new distinct sub-arrays will be [1,3,6] .. to [1,3,6,3,6,3,1,3] i.e. 6 sub-arrays.
So new value of ANS is 2+6 = 8;
So for pair[i] and pair[i+1]
ANS = ANS + Number of sub-arrays beginning from pair[i+1] - Length of longest common prefix.
The sorting part takes O(n logn).
Iterating each consecutive pair is O(n) and for each iteration find longest common prefix takes O(n) making whole iteration part O(n^2). Its the best I could get.
You can see that we dont need pair for this. The first value of pair, value of element was not required. I used this for better understanding. You can always skip that.

Resources