What is the result of the following code? - c

Why the result is 7??? I can't find the log if that :(
#include <stdio.h>
main() {
int i, j, a = 1, b = 1;
for (i = 1; i < 4; i++)
for (j = 1; j < 3; j++)
a = a + b;
printf("a=%d", a);
}

The structure is like below
- Outer `for` loop
- inner `for` loop
- instruction
so the "instruction" (statement/block) will get executed inner for loop count times, for outer for loop count times.
What is basically says is, add the value of b to the latest value of a (in a recurring way) to get the current value of a. Now , do that for "outer" number of time, for which, do the same for "inner" number of times.
Outer for loop ==> 3 times,
inner for loop ==> 2 times
So, final value =3*2 (increment) + (initial) = (3*2)*1 + 1 = 7.

The result is 7 because b is initialized as 1 and stays 1 the whole time. The outer loop is run 3 times (1, 2, 3), the inner loop is run 2 times (1 and 2), so there are 6 runs where b is added to a (which is initialized as 1). 1 + 6 = 7.

In such scenarios, you should add a watch and debug your code line by line. I believe the shortcut is F11. Regards to why the output of your code is 7...
The inner loop runs six times. J loops twice - 1, 2, (ends when it is 3), and I loops thrice (1, 2, 3, 4 - end)... for a total of 2 X 3 = 6.
Since b is '1', you are basically adding the number 1 to a six times. Since a started with '1', the output is:
a = 1 + 1 + 1 + 1 + 1 + 1 + 1 = 7

Related

Index exceeds the number of array elements (9) in MATLAB

So I am getting an error where I believe n1 is larger than the array after n becomes n = 3, which is giving the error in ma. Premise of the code is to take 1 2, 3 4 5, 6 7 8 9, etc. and average each group. Pretty sure I have to change the length but not sure how to go about it. What should I do? Here is the code:
clear all
mdata = [1 2 3 4 5 6 7 8 9];
n1 = 1;
k = 1;
for n = 1:length(mdata)
ma(n) = (1/(k + 1)) * sum(mdata(n1:n1 + k));
n1 = ((n1 + k) + 1);
k = k + 1;
std_ma = std(mdata);
end
Error message:
Index exceeds the number of array elements (9).
Error in untitled22 (line 11)
ma(n) = (1/(k + 1)) * sum(mdata(n1:n1 + k));
The issue is that you are replacing the value of n1 with n1+k+1 on each step through the loop. At the start of the 4th iteration, n1=10 and k=4, meaning you are trying to take the sum of elements 10:14 but the array only has 9 elements.
It is not clear from your question exactly what averages you are trying to calculate through all of the iterations of the loop and so it is difficulty to say more. But, most likely, you do not need to manually calculate the average yourself. Just define the subset of the data you want to work with on that iteration and take the mean of that.
I am also guessing that you want to modify the assignment of std_ma at the end of your loop to only perform the std on the subset of data you are working with. Currently you are doing the calculation over all values in mdata and repeating that same calculation 9 times.

Understanding control structure of nested loops in Python

All of the options below produce the same output, but I'm not quite understanding why. Is anyone able to explain why multiple values are printed for j on each line? I would think it would print either 0 every time when it is set equal to 0 or print 1, 2, 3, 4 instead.
Option 1:
for i in range(1, 6):
j = 0
while j < i:
print(j, end = " ")
j += 1
print("")
Option 2:
for i in range(1, 6):
for j in range(0, i):
print(j, end = " ")
print("")
Option 3:
i = 1
while i < 6:
j = 0
while j < i:
print(j, end = " ")
j += 1
i += 1
print("")
Output:
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
It is because of the inner while/for loop that one or more digits are printed on a single line.
As the value of i increments in the outer loop, the number of nested iterations increase with increasing value of i.
The digits are printed on the same line in inner loop due to end=" " argument to the first print statement and the next sequence appears on the new line because the second print statement in the outer iteration does not contain any such argument.
In order to gain better understanding, make following changes to your code, one by one and test run to see the effects:
Replace i in the inner loop with some constant value
Replace the space in end = " " with something else, e.g. end = "x"

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.

Add values in array and compare with threshold within loop in Matlab

I am stuck trying to figure this out. I have an array:
a = [ 1 1 1 2 1 1 1 3 2 1 1 2 1 1 1]
I want to add the values in the array so that it equal to 10. Once the added value reaches 10, I want the array to start adding the value again until it reaches 10. There is two problem that I face here,
1) How can I add the array so that the sum = 10 everytime. Notice that in the array, there is 3. If I add all the value before 3, I get 8 and I only need 2 from 3. I need to make sure that the remainder, which is 1 is added to the next array to get the sum 10.
2) How do I break the loop once it reaches 10 and ask it continue the summation to next value to get another 10?
I created a loop but it only works for the first part of the array. I have no idea how to make it continue. The code is as follow:
a = [ 1 1 1 2 1 1 1 3 2 1 1 2 1 1 1];
c = 0;
for i = 1:length(a)
while c < 10
c = c + a(i);
break
end
end
Please help. Thank you
This can be done using cumsum, mod, diff and find as follows:
temp = cumsum(a);
required = find([0 diff(mod(temp,10))] <0)
cumsum returns the cumulative sum which then is rescaled using mod. diff determines where the sum gets greater than or equal to 10 and finally find determines those indexes.
Edit: Above solution works if a doesn't have negative elements. If a can have negative elements then:
temp1=cumsum(a); %Commulative Sum
temp2=[0 diff(mod(temp1,10))];%Indexes where sum >=10 (indicated by negative values)
temp2(temp1<0)=0; %Removing false indexes which may come if `a` has -ve values
required = find(temp2 <0) %Required indexes
This should do what you are trying. It displays the index at which each time the sum equals 10. Check this with your testcases. rem stores the residual sum in each iteration which is carried forward in the next iteration. The rest of the code is similar to what you were doing.
a = [ 1 1 1 2 1 1 1 3 2 1 1 2 1 1 1];
c = 0;
rem = 0;
i = 1;
length(a);
while(i <= length(a))
c = rem;
while (c < 10 && i <= length(a))
c = c + a(i);
i = i + 1;
if(c >= 10)
rem = c - 10;
break
end
end
if(c >= 10)
disp(i-1)
end
use cumsum instead of your while loop:
a = [ 1 1 1 2 1 1 1 3 2 1 1 2 1 1 1];
a_ = a;
endidxlist = false(size(a));
startidxlist = false(size(a));
startidxlist(1) = true;
while any(a_) && (sum(a_) >= 10)
b = cumsum(a_);
idx = find(b >= 10,1);
endidxlist(idx) = true;
% move residual to the next sequence
a_(idx) = b(idx) - 10;
if a_(idx) > 0
startidxlist(idx) = idx;
elseif (idx+1) <= numel(a)
startidxlist(idx+1) = true;
end
a_(1:idx-1) = 0;
end
if (idx+1) <= numel(a)
startidxlist(idx+1) = false;
end
endidxlist gives you the end-indexes of each sequence and startidxlist the start-indexes

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