Race condition scenario - c

I have a question regarding a race condition scenario. The question:
Consider the following two threads, to be run concurrently in a shared
memory (all variables are shared between the two threads).
Thread A
for i = 1 to 5 do
x = x + 1;
Thread B
for j = 1 to 5 do
x = x + 1;
Assuming a single-processor system, that load and store are atomic,
that x is initialized to 0, and that x must be loaded into a register
before being incremented (and stored back to memory afterwards), what
are all the possible values for x after both threads have completed?
Now the answer is 2:10 inclusive. I understand the results of 5:10, but how could x be 2, 3 or 4?

Sequence to get x = 2:
Thread 2 read // Reg_2 = 0
Thread 1 read/write 4 times // x = 4
Thread 2 write // * Reg_2 = 0 --> x = 1
Thread 1 read // Reg_1 = 1
Thread 2 read/write 4 times // x = 5
Thread 1 write // Reg_1 = 1 --> x = 2
Depending on how many write thread 2 does before you preempt at the step marked with *, you will get the result for 3 and 4.

Related

Cs50 PSET 1 Mario less comfortable

hey thanks for the help:screenshot
New to programming and trying to understand the logic why the code in line 17 produces the desire result of a left-aligned pyramid. Just trying to fully understand why x= height - y - 1 gives the desired outcome.
This snippet
for (int x = height - y - 1; x < height; x++)
{
print("#");
}
does not have anything to do with alignment. The pyramid will always be left aligned without a space(" ") printing loop, which you don't have in your code and you probably don't need either.
Now let's walk through the iteration to understand what's going on
Consider the height to be 5
In the first iteration of the outer loop (i.e for (int y = 0; y < height; y++))
y = 0
x = height - y - 1 = 5 - 0 - 1 = 4
So x starts at 4 and stops before reaching height, i.e 5. So this loop will be executed exactly 1 time. Which means it'll print a singular #.
In the second iteration of the outer loop
y = 1
x = height - y - 1 = 5 - 1 - 1 = 3
So x starts at 3 and stops before reaching height, i.e 5. So this loop will be executed exactly 2 times. Which means it'll print # twice.
In the third iteration of the outer loop
y = 2
x = height - y - 1 = 5 - 2 - 1 = 2
So x starts at 2 and stops before reaching height, i.e 5. So this loop will be executed exactly 3 times. Which means it'll print # thrice.
In the fourth iteration of the outer loop
y = 3
x = height - y - 1 = 5 - 3 - 1 = 1
So x starts at 1 and stops before reaching height, i.e 5. So this loop will be executed exactly 4 times. Which means it'll print # 4 times.
In the fifth and final iteration of the outer loop
y = 4
x = height - y - 1 = 5 - 4 - 1 = 0
So x starts at 0 and stops before reaching height, i.e 5. So this loop will be executed exactly 5 times. Which means it'll print # 5 times.
So to achieve that logic, is the reasoning behind using x = height - y - 1. However there are other ways to do this too-
for (int x = 0; x < y + 1; x++)
{
print("#");
}
This will also work in the same logic, but hopefully with less confusion.
Notice, how the number of characters printed in each line matches with the line number. So the first line has 1 hash, 2nd has 2 and so on. We can deduce the line number from y. For the first line y = 0, for the second line y = 1 and so on. So we can simply add 1 to y and set that as our upper bound to print the hashes.

Find a duplicate in array of integers

This was an interview question.
I was given an array of n+1 integers from the range [1,n]. The property of the array is that it has k (k>=1) duplicates, and each duplicate can appear more than twice. The task was to find an element of the array that occurs more than once in the best possible time and space complexity.
After significant struggling, I proudly came up with O(nlogn) solution that takes O(1) space. My idea was to divide range [1,n-1] into two halves and determine which of two halves contains more elements from the input array (I was using Pigeonhole principle). The algorithm continues recursively until it reaches the interval [X,X] where X occurs twice and that is a duplicate.
The interviewer was satisfied, but then he told me that there exists O(n) solution with constant space. He generously offered few hints (something related to permutations?), but I had no idea how to come up with such solution. Assuming that he wasn't lying, can anyone offer guidelines? I have searched SO and found few (easier) variations of this problem, but not this specific one. Thank you.
EDIT: In order to make things even more complicated, interviewer mentioned that the input array should not be modified.
Take the very last element (x).
Save the element at position x (y).
If x == y you found a duplicate.
Overwrite position x with x.
Assign x = y and continue with step 2.
You are basically sorting the array, it is possible because you know where the element has to be inserted. O(1) extra space and O(n) time complexity. You just have to be careful with the indices, for simplicity I assumed first index is 1 here (not 0) so we don't have to do +1 or -1.
Edit: without modifying the input array
This algorithm is based on the idea that we have to find the entry point of the permutation cycle, then we also found a duplicate (again 1-based array for simplicity):
Example:
2 3 4 1 5 4 6 7 8
Entry: 8 7 6
Permutation cycle: 4 1 2 3
As we can see the duplicate (4) is the first number of the cycle.
Finding the permutation cycle
x = last element
x = element at position x
repeat step 2. n times (in total), this guarantees that we entered the cycle
Measuring the cycle length
a = last x from above, b = last x from above, counter c = 0
a = element at position a, b = elment at position b, b = element at position b, c++ (so we make 2 steps forward with b and 1 step forward in the cycle with a)
if a == b the cycle length is c, otherwise continue with step 2.
Finding the entry point to the cycle
x = last element
x = element at position x
repeat step 2. c times (in total)
y = last element
if x == y then x is a solution (x made one full cycle and y is just about to enter the cycle)
x = element at position x, y = element at position y
repeat steps 5. and 6. until a solution was found.
The 3 major steps are all O(n) and sequential therefore the overall complexity is also O(n) and the space complexity is O(1).
Example from above:
x takes the following values: 8 7 6 4 1 2 3 4 1 2
a takes the following values: 2 3 4 1 2
b takes the following values: 2 4 2 4 2
therefore c = 4 (yes there are 5 numbers but c is only increased when making steps, not initially)
x takes the following values: 8 7 6 4 | 1 2 3 4
y takes the following values: | 8 7 6 4
x == y == 4 in the end and this is a solution!
Example 2 as requested in the comments: 3 1 4 6 1 2 5
Entering cycle: 5 1 3 4 6 2 1 3
Measuring cycle length:
a: 3 4 6 2 1 3
b: 3 6 1 4 2 3
c = 5
Finding the entry point:
x: 5 1 3 4 6 | 2 1
y: | 5 1
x == y == 1 is a solution
Here is a possible implementation:
function checkDuplicate(arr) {
console.log(arr.join(", "));
let len = arr.length
,pos = 0
,done = 0
,cur = arr[0]
;
while (done < len) {
if (pos === cur) {
cur = arr[++pos];
} else {
pos = cur;
if (arr[pos] === cur) {
console.log(`> duplicate is ${cur}`);
return cur;
}
cur = arr[pos];
}
done++;
}
console.log("> no duplicate");
return -1;
}
for (t of [
[0, 1, 2, 3]
,[0, 1, 2, 1]
,[1, 0, 2, 3]
,[1, 1, 0, 2, 4]
]) checkDuplicate(t);
It is basically the solution proposed by #maraca (typed too slowly!) It has constant space requirements (for the local variables), but apart from that only uses the original array for its storage. It should be O(n) in the worst case, because as soon as a duplicate is found, the process terminates.
If you are allowed to non-destructively modify the input vector, then it is pretty easy. Suppose we can "flag" an element in the input by negating it (which is obviously reversible). In that case, we can proceed as follows:
Note: The following assume that the vector is indexed starting at 1. Since it is probably indexed starting at 0 (in most languages), you can implement "Flag item at index i" with "Negate the item at index i-1".
Set i to 0 and do the following loop:
Increment i until item i is unflagged.
Set j to i and do the following loop:
Set j to vector[j].
if the item at j is flagged, j is a duplicate. Terminate both loops.
Flag the item at j.
If j != i, continue the inner loop.
Traverse the vector setting each element to its absolute value (i.e. unflag everything to restore the vector).
It depends what tools are you(your app) can use. Currently a lot of frameworks/libraries exists. For exmaple in case of C++ standart you can use std::map<> ,as maraca mentioned.
Or if you have time you can made your own implementation of binary tree, but you need to keep in mind that insert of elements differs in comarison with usual array. In this case you can optimise search of duplicates as it possible in your particular case.
binary tree expl. ref:
https://www.wikiwand.com/en/Binary_tree

swapping two vector's elements in matlab

I have two vectors, v1 (1x9) and v2 (1x4).
I have to write a function with two inputs, (x,y) and output of out.
x should be the index number x in v1.
y should be the index number y in v2.
The function should replace the xth element in v2 with the ythelement in v1 and give the new v2 as output.
As an example:
v1=[1 2 3 4 5 6 7 8 9];
v2=[1 2 3 4];
out = myfun(7,2);
then the output should be
out = [1 7 3 4];
The next time if x=9 and y=1
out = myfun(9,1);
out = [9 7 3 4];
my main program idea is
[M Z]=test(A,q)
A is matrix (mxn)
q is vector of length m
i=[1:m];j=[1:n];
c(:,j)=q./A(:,j);
find minimum element in c . as example it is c(I,j) then
x=I; and y=j;g
i = [1:x-1,x+1:m]; j = [1:y-1,y+1:n]; % starting new calculations
statements…calculation procedures to find matrix M instead of A and vector Z instead of q.
end of program
now I want to write myfunction which you did before inside this program
elseif v(x) <= v1(n) this program must working continuously (holding M and Z as new A and q in input and get the minimum ratio and so the new x and y ) until v(x)==n break
please help
You can save the variable and load it in the next call.
function v2 = myfun(x,y)
v1=[1 2 3 4 5 6 7 8 9];
v2=[1 2 3 4];
if exist('v2.mat', 'file' ) ~= 0
load('v2')
end
v2(y) = v1(x);
save('v2','v2');
end
You could also use persistant variable,
function out = myfun(x,y)
persistent v
if isempty(v)
v = [1 2 3 4];
end
v1=[1 2 3 4 5 6 7 8 9];
v(y) = v1(x);
out = v;
end
Note
mlock command locks the currently running function in memory so that subsequent clear functions do not remove it. Locking a function in memory also prevents any persistent variables defined in the file from getting reinitialized.
Edit
I got this form your comments, see how it goes,
function out = test(x,y)
persistent v
if isempty(v)
v = [1 2 3 4];
end
v1 = [1 2 3 4 5 6 7 8 9];
v(y) = v1(x);
if x == 3;
out = v;
return
elseif v(y) <= v1(9)
statements
end
out = v;
end

Carrying out of loop so as to do the following operation

consider an area with size m*n. Here the size of m and n is unknown. Now I am extracting data from each point in the area. I am scanning the area first going in the x direction till m point and the again returning to m=0 and n=1, i.e the second row. Again I scan along the x direction till the end of m. An example of the data has been shown below. Here I get value for different x,y coordinates during the scan. I can carry out operation between the first two points in x direction by
p1 = A{1}; %%reading the data from the text file
p2 = A{2};
LA=[p1 p2];
for m=1:length(y)
p= LA(m,1);
t= LA(m,2);
%%and
q=LA(m+1,1)
r=LA(m+1,2)
I want to do the same for y axis. That is I want to operate between first point in x=0 and y=1 then between x=2 and y=1 and so on. Hope you have got it.
g x y
2 0 0
3 1 0
2 2 0
4 3 0
1 4 0
2 m 0
3 0 1
2 1 1
4 2 1
5 3 1
.
.
.
.
2 m 1
now I was thinking of a logic where I will first find the size of n by counting the number of zeros
NUMX = 0;
while y((NUMX+1),:) == 0
NUMX = NUMX + 1;
end
NU= NUMX;
And then I was thinking of applying the following loop
for m=1:NU:n-1
%%and
p= LA(m,1);
t= LA(m,2);
%%and
q=LA(m+1,1)
r=LA(m+1,2)
But its showing error. Please help!!
??? Attempted to access del2(99794,:); index out of bounds because
size(del2)=[99793,1].
Here NUMX=198
Comment: The nomenclature in your question is inconsistent, making it difficult to understand what you are doing. The variable del2 you mention in the error message is nowhere to be seen.
1.) Let's start off by creating a minimal working example that illustrates the data structure and provides knowledge of the dimensions we want to retrieve later. You matrix is not m x n but m*n x 3.
The following example will set up a matrix with data similar to what you have shown in your question:
M = zeros(8,3);
for J=1:4
for I=1:2
M((J-1)*2+I,1) = rand(1);
M((J-1)*2+I,2) = I;
M((J-1)*2+I,3) = J-1;
end
end
M =
0.469 1 0
0.012 2 0
0.337 1 1
0.162 2 1
0.794 1 2
0.311 2 2
0.529 1 3
0.166 2 3
2.) Next, let's determine the number of x and y, to use the nomenclature of your question:
NUMX = 0;
while M(NUMX+1,3) == 0
NUMX = NUMX + 1;
end
NUMY = size(M,1)/NUMX;
NUMX =
2
NUMY =
4
3.) The data processing you want to do still is unclear, but here are two approaches that can be used for different means:
(a)
COUNT = 1;
for K=1:NUMX:size(M,1)
A(COUNT,1) = M(K,1);
COUNT = COUNT + 1;
end
In this case, you step through the first column of M with a step-size corresponding to NUMX. This will result in all the values for x=1:
A =
0.469
0.337
0.794
0.529
(b) You can also use NUMX and NUMY to reorder M:
for J=1:NUMY
for I=1:NUMX
NEW_M(I,J) = M((J-1)*NUMX+I,1);
end
end
NEW_M =
0.469 0.337 0.794 0.529
0.012 0.162 0.311 0.166
The matrix NEW_M now is of size m x n, with the values of constant y in the columns and the values of constant x in the rows.
Concluding remark: It is unclear how you define m and n in your code, so your specific error message cannot be resolved here.

Increment values in an array with constraints using Matlab?

Scenario :
If I have an array with 4 loads (a1 a2 a3 a4)
a=[a1 a2 a3 a4] (locations of these loads must be fixed)
a=[1 2 3 3]
I would like to try and increase all values in the array to 3.
Note : the array a is not fixed, and can have any value from 0:3
Constraints :
There is a priority array that cannot be violated
Number of total increments is limited to 3
Given :
Priority array v=[1 3 2 1] -- (1 is highest priority, and 3 is lowest priority).
Note : the array v is not fixed, and can have any value from 0:3
Using this priority array :
a(1,1)=highest priority
a(1,4)=2nd highest priority
a(1,3)=3rd priority
a(1,2)=lowest priority
Implementation, my trial in pseudo code :
a=[1 2 3 3]
v=[1 3 2 1]
count=3
Check highest priority : a(1,1)
increment by 1
decrement count by 1
count = 2
still less than 3 ? if yes, then increment again until a(1,1)<= 3 AND count >=0
Change highest priority to 5 (so that min(v) will not pick it up)
ans : a=[3 2 3 3] ; v=[5 2 3 3] ; count = 1
Check highest priority : a(1,3)
value >= 3
Change highest priority to 5 (so that min(v) will not pick it up)
skip
ans : a=[3 2 3 3] ; v=[5 2 5 3] ; count = 1
Check highest priority : a(1,4)
value >=3
Change highest priority to 5 (so that min(v) will not pick it up)
skip
ans : a=[3 2 3 3] ; v=[5 2 5 5] ; count = 1
Check highest priority : a(1,2)
increment by 1
decrement count by 1
count = 0
still less than 3 ? if yes, then increment again until a(1,1)<= 3 AND count >=0
Change highest priority to 5 (so that min(v) will not pick it up)
ans = [a1 a2 a3 a4] = [3 3 3 3]
Note : if a priority value = [1 1 1 1] is reached, then a is prioritised from left to right (I haven't found a better way to do this)
I hope this makes sense, and that my pseudo code shows what I'm trying to implement. Ask me if something is not clear.
You could do something like this
a = [1 2 3 3];
v = [1 3 2 1];
% Sort a in the order of priority v
[vSrt, indSrt] = sort(v);
a = a(indSrt);
nIncsRemaining = 3; % Total no. of increments allowed
target = 3; % Target value for each value in a
for curInd = 1:length(a)
% Difference from target
aDiff = target - a(curInd);
% Do we need to increment this value of a?
if aDiff > 0
% Increment by a maximum of nIncsRemaining
aDelta = min(aDiff, nIncsRemaining);
% Increment a and decrement no. of increments remaining by the
% same amount
a(curInd) = a(curInd) + aDelta;
nIncsRemaining = nIncsRemaining - aDelta;
end
% Have we done as much as we're allowed?
if nIncsRemaining == 0, break; end
end
The key step is the sorting of the priority array, and the sorting of a by the same indices. Then you can just loop through a, being confident that you're beginning with the highest priority.
If you require the same order as the input at output, then you can invert the sorting operation by doing
[~, indReSrt] = sort(indSrt);
a = a(indReSrt);
The array v was not modified in the first place, so you don't need to invert the sort on that array.
Here's what I came up with:
a = [1 2 3 3];
v = [1 3 2 1];
% Get priority vector - this converts v into the indices of a that are most important in descending order. This can also be preallocated for speed or stored in place if v is not important;
priority_vec = [];
for i = 0:3
% Get indices
priority_vec = horzcat(priority_vec,find(v == i));
end
% Loop over priority_vec
count = 3; % count is the number of additions you can make
for i = 1:4 % Loop over the indices of priority vec
priority_ind = priority_vec(i); % This is the current index of most importance
while(a(priority_ind) < 3 && count ~= 0) % Continue to add one while count is greater than 0 and the value at the priority index is less than three
a(priority_ind) = a(priority_ind) + 1;
count = count - 1;
end
end
Another version:
a = [1 2 3 3];
v = [1 3 2 1];
count = 3;
target = 3;
Sort a and v in priority order
[vSorted, order] = sort(v);
aSorted = a(order);
Find position that will cause count to equal 0
pos = find(cumsum(target - aSorted) >= count);
Update all values up until but not including pos, decrement count accordingly
count = count - sum(3 - aSorted(1:pos - 1));
vSorted(1:pos - 1) = 5;
aSorted(1:pos - 1) = target;
Update the value s at pos
aSorted(pos) = aSorted(pos) + count;
count = 0;
if aSorted(pos) == target
vSorted(pos) = 5;
end
Restore sort order
[~, invOrder] = sort(order);
a = aSorted(invOrder);
v = vSorted(invOrder);
If v is only used to determine the priority there is no need to update it.
If count may still be non-zero after all values of a have reached target some extra handling of that case is required as that will cause pos = find(...); to return an empty array.

Resources