How to make an O(N) algorithm solution? [duplicate] - arrays

This question already has answers here:
Equilibrium index of an array of large numbers, how to prevent overflow?
(2 answers)
Closed 7 years ago.
This problem is a practice problem found on Codility, a link can be found here to an example. https://codility.com/public-report-detail/
Problem: We have an array of N integers -- where 0 <= N < 100,000 -- where each integer is between -2,8XX,XXX and +2,8XX,XXX (signed int range). The challenge is to find whether there exists a point, P, where the summation of all array values prior to P are equal to the summation of those after P.
i.e. sum(A[0] to A[P-1]) == sum(A[P+1] to A[N-1])
ex.
A[0] = -1
A[1] = 3
A[2] = -4
A[3] = 5
A[4] = 1
A[5] = -6
A[6] = 2
A[7] = 1
P = 1 is an equilibrium index of this array, because:
A[0] = −1 = A[2] + A[3] + A[4] + A[5] + A[6] + A[7]
P = 3 is an equilibrium index of this array, because:
A[0] + A[1] + A[2] = −2 = A[4] + A[5] + A[6] + A[7]
P = 7 is also an equilibrium index, because:
A[0] + A[1] + A[2] + A[3] + A[4] + A[5] + A[6] = 0
The program can quit after the first instance of an acceptable P is found.
There was 30 minutes to complete the challenge, and evidently the expected solution is O(N). I can think of a few O(NlogN) solutions to the problem -- and an O(N) solution involving the summation of the array before removing values one at a time, but this wouldn't work for extreme cases in which every value is of 2,8XX,XXX,XXX.
I'm working in C++ but even pseudo would be great. Suggestions on the proper algorithm to handle this constraint?

A version that works if you can use 64-bit integers: Calculate the cumulative sum of the array, then copy the array and calculate the cumulative sum again from the back. Then step through both cumulative sums and where the value at a given index is equal in both, you have P.
E.g., your example array becomes
-1 2 -2 3 4 -2 0 1
and
1 2 -1 3 -2 -3 3 1
* * *
where the P points have been marked with an asterisk.
If you can't use 64-bit integers outright, then I guess I would make additional arrays for remainders, i.e. manually recreate 64-bit functionality with another signed int array, and require both arrays to match when checking. I don't think there's anything else you could do under this general approach.

Related

Counting by multiples in c byte array

Im trying to reduce the information density of an RGB pixel in a 2d barcode for scanning.
I currently have a 3 byte array where information is encoded in multiples of bound until 256 is hit, at which point it will loop over to the next byte; For instance if bound was 60:
0,0,0 -> 60,0,0 -> 120,0,0 -> 180,0,0 -> 240,0,0 -> (loop over) 0,60,0 -> ...
I suspect there is a very simple method to do this, but i have only been able to implement this with a for loop
void multiples(uint32_t data){
uint32_t a[3] = {0, 0, 0};
uint8_t bound = 32;
for(int i = 0; i < data; i++){
a[0] += bound;
a[1] += bound*(a[0] - a[0]%256)/256;
a[2] += bound*(a[1] - a[1]%256)/256;
a[0] %= 256;
a[1] %= 256;
}
printf("%u,%u,%u\n",a[0],a[1],a[2]);
}
How should this be done optimally?
Your example does not match the code and your explanation. But assuming that your code is correct, I think that we can optimize it. Since you are adding bound constantly to a[0], the cumulative value of a[0] (say, acc[0]) will be,
acc[0] = data * bound
So a[0] can be directly computed as acc[0] % 256. Now the cumulative value of a[1] is adding bound whenever acc[0] crosses a multiple of 256. Therefore,
acc[1] = (acc[0]/256)*bound
So a[1] will be acc[1]%256. Cumulative a[2] similarly is the number of times acc[1] crosses a multiple of 256.
acc[2] = (acc[1]/256)*bound
I think the requirement must be a[2] to be less than 256, so a[2] should be acc[2]%256. But you can keep it equal to acc[2] as in the code.

i am struck with the Flow of execution, can anyone help me out

I am confused how the expression get executed for the following code.
#include<stdio.h>
int main()
{
int a[10];
a[0] = 1;
a[1] = 2;
printf("%d %d",a[0],a[1]);
a[0] = a[0] - (a[0] = a[1]); // not able to understand its flow of execution
printf("\n%d %d",a[0],a[1]);
}
The output for this is
1 2
-1 2
My doubt is where the assignment operator inside that parenthesis get executed and change the a[0] element, and is used in expression, such as
index : 0 1
element : 1 2
during expression : 2 2 // when (a[0] = a[1])
a[0] = a[0] - (a[0] - a[1]);
a[0] = 1 - (2);
a[0] = -1;
(or)
index : 0 1
element : 1 2
during expression : 1 2 // when (a[0] = a[1])
a[0] = a[0] - (a[0] - a[1]);
a[0] = 1 - (2);
a[0] = -1;
also the associative property also confused whether expression is seen from left to right or right to left.
Your code has undefined behavior.
a[0] = a[0] - (a[0] = a[1]);
By itself, the subexpression (a[0] = a[1]) is valid. It assigns the value of a[1] to a[0], and yields the value that was assigned.
The problem is that a[0] is modified twice in a single expression, and the two modifications are unsequenced, meaning that the language doesn't tell us which one happens first. (In C90/C99 terms, the two modifications are not separated by a sequence point.)
A simpler example of this:
x = 2 + (x = 1);
Here x is modified twice. The language doesn't just say that the two modifications can happen in either order; it says that the behavior is undefined. In other words, the language says nothing about what will happen. It could crash, it could give you some garbage results, or, worst of all, it could do just what you expect it to do. (That's the worst case because it means you still have a serious bug that's going to be difficult to detect and diagnose it.)
Bottom line: Whatever that line of code was intended to do, there is certainly a clearer and less ambiguous way to do it. The code in your question, not to be too harsh, might as well not even be C.

Given a sequence a[1], a[2], ..., a[n], find an array b[1] < b[2] < ... < b[n] such that |a[1]-b[1]| + |a[2]-b[2]| + ... + |a[n]-b[n]| is minimum

I've recently stumbled upon the following problem:
Given a sequence a[1], a[2], ..., a[n], find an array b[1] < b[2] < ... < b[n] such that |a[1]-b[1]| + |a[2]-b[2]| + ... + |a[n]-b[n]| is minimum.
I have already come up with some observations, but I still couldn't figure out any feasible solution.
I don't know the expected time complexity, nor do I know the solution. But it is given that n <= 10^6.
The problem is from BOI 2003, and is called Sequence.
Input
9 4 8 20 14 15 18
Output
6 7 8 13 14 15 18
Since the difference is 13.

Logical Arrays - In an assignment A(I) = B, the number of elements in B and I must be the same

I have three matrices, A, B and C. When B is larger than A, I want to saturate the value with A. It says that the number of elements in I (which is (B > A)) must be the same as the number of elements in A. I checked below and they are the same.
>> A = [5 5 5; 5 5 5; 5 5 5];
>> B = [2 2 2; 2 2 2; 2 2 2];
>> C(B > A) = A
In an assignment A(I) = B, the number of elements in B and I must be the same.
>> numel(B > A)
ans =
9
>> numel(A)
ans =
9
>> numel(A>B)
ans =
9
It is also strange that this works.
>> C(B < A) = A
C =
5 5 5 5 5 5 5 5 5
I just figured it out...
C(B>A) = B(B>A)
C =
5 5 5 5 5 5 5 5 5
The reason why is because B > A is never satisfied, and produces the empty set. This will produce the empty matrix ([]). Every element of B is actually smaller than A. As such, this is equivalent to performing:
C([]) = A;
You are trying to assign A to nowhere in the matrix, and those dimensions don't match. The reason why B < A works is because every value of B is less than A, and so the assignment of A will work here. In general, you need to make sure that the total number of elements you are accessing on the right side of the expression must equal the same number of elements on the left hand side of the expression you want to assign the elements to.
As you have mentioned in your comments, doing:
C(B > A) = B(B > A)
will work. This is equivalent to doing:
C([]) = B([]);
... essentially, you are performing nothing, so this is a safe operation. No values are being accessed in B are being assigned to locations in A.
B>A is a logical 3x3 matrix, but C(B>A) is the empty set, and you are assigning a 3x3 matrix to it. Thus the error.
Try
C(B>A)=A(B>A);
On the other hand, C(B < A) is C, a 3x3 matrix, so C(B < A) is C, to which you can assign A.

different representation of array element [duplicate]

This question already has answers here:
With arrays, why is it the case that a[5] == 5[a]?
(20 answers)
Closed 9 years ago.
consider following C code
int a[]={1,2,3,4};
printf("%d",2[a]);
this prints "3".How is it possible? I know in a[2] a is the base address of array.But in 2[a]
what is 2? and how it accessses array a?I am totally confused with this representation of array.
There are two things to remember here:
The first is that array access is basically just a fancy way of using pointer arithmetic. For example, if you have the array
int a[10];
then
a[3] = 5;
is equal to
*(a + 3) = 5;
The second thing to remember is that addition (like in a + 3 above) is commutative, so a + 3 is the same as 3 + a. This leads to e.g.
*(3 + a) = 5;
which can be interpreted as
3[a] = 5;
int a[]={1,2,3,4}; is an integer array containing 4 elements and a is the Base Address, Let the Base Address be denoted by X . Now a[1] means element at address X + sizeOf(int) * 2 = Y (suppose) i.e. element at address Y, likewise 2[a] means element at adsress sizeOf(int) * 2 * X = Y.
Thus even if you write a[2] or 2[a] eventually complier recognizes it as Y and refres to the element at address Y which is 3 in our case.
Hope it addresses the problem right.
*(expr1+expr2) is equivalent to expr1[expr2] or expr2[expr1].
*(expr2+expr1) is equivalent to expr2[expr1] or expr1[expr2].
It is just another way to write an element of an array.
In int a[]={1,2,3,4};, element at index 3 can be referenced by many methods:
As an array element: a[3]
Using pointer: *(a + 3) or *(3 + a) [Addition is commutative in arithmetics and in C]
Now you can write the second way of representation using pointer as 3[a], i.e. a[3] is equal to *(a + 3) is equal to *(3 + a) is equal to 3[a].

Resources