How to can I count the number of ones? - matlab

The problem is:
In a class of 26 students, a test with 10 questions is given. The students answer the question by tossing a coin. I have to find out how many students have two or less answers correct. This is the program that I wrote, but I'm not sure about it ... is it good?
correct=0;
students=0;
for i=1:26
for j=1:10
answ=ceil(rand);
if answ==1
correct=correct+1;
if correct==2
students=students+1;
end
end
end
end
disp(students)

It's neater, faster to run, and more readable if you do it vectorized:
answers = round(rand(10,26)); % 10x26 matrix of 0 / 1 values
correct = sum(answers); % sum along each column
students = sum(correct<=2) % how many values of correct are 2 or less
By the way, from your code it appears you want to know how many students have 2 or more correct answers (not 2 or less as you state). In that case change last line to
students = sum(correct>=2) % how many values of correct are 2 or more

Slight modification to your code:
correct=0;
students=0;
for i=1:26
for j=1:10
answ=round(rand); % Use round instead of ceil
if (answ==1)
correct=correct+1;
if correct==2
students=students+1;
break;
end
end
end
correct=0; % Was missing in original code
end
disp(students)
Additional Note:
Try testing code for correct ans 5 as this will have more chances of variation to result because of uniform distribution of random number. Most of the students will get at-least 2 correct ans assuming equal probability, which is not the practical case.
Try maintaining habit of proper indentation. It will be more readable and less prone to errors.

Just like this : (You have to reset correct counter for every student, and some end aren't at the right place.)
correct = 0;
students = 0;
for i = 1:26
for j = 1:10
answ = ceil(rand);
if(answ==1)
correct = correct + 1;
end
end
if(correct < 2)
students = students + 1;
end
correct= 0;
end
EdIT
Sorry, I didn't saw the less in your sentense, so I change the > for <

Related

Run the for loop only once Matlab

total_Route = zeros(4,4);
tmp = evalin('base', 't'); % i initialise t in the Workspace with the value 1
if(tmp==5)
tmp=1;
end
total_Route(tmp,1) = Distance_Traveled_CM;
total_Route(tmp,2) = Hauptantrieb_Verbrauchte_Energie_CM;
total_Route(tmp,3) = Nebenaggregate_Verbrauch_Real_CM;
total_Route(tmp,4) = t;
Total_Distance_Traveled_CM = sum(total_Route(:,1));
set(handles.edit3, 'string',Total_Distance_Traveled_CM);
Total_Hauptantrieb_Verbrauchte_Energie_CM = sum(total_Route(:,2));
set(handles.edit4, 'string',Total_Hauptantrieb_Verbrauchte_Energie_CM);
Total_Nebenaggregate_Verbrauch_Real_CM = sum(total_Route(:,3));
set(handles.edit5, 'string',Total_Nebenaggregate_Verbrauch_Real_CM);
%% Index
set(handles.edit15, 'string',tmp);
assignin('base', 't', tmp + 1); % with this line i can increment "t" after each pass
guidata(hObject,handles);
Sorry that I did not explain my problem well.
#Sardar_Usama I want to run the loop only once but t should be incremented after each time I click on my Button.
# Sembei Norimaki end is at the end of my codes, have forgotten to write it in my question
#Patrik & #Dennis Jaheruddin let me explain my problem again
I created a Matrix with 4×4 Elements with the Goal to save the results of each my Variable (Total_Distance_Traveled_CM, Total_Hauptantrieb_Verbrauchte_Energie_CM etc...) after each Simulation in the element of my Matrix (See image below).
I want by pressing a button (on my GUI) to get always the sum of each Column.
Example
The first pass: t = 1--> Distance_Traveled(1,1) is 900 the GUI will take through clicking on the Button, the sum of the first column (which is 900+0+0+0) and write it in a static test.
The second pass t = 2--> Distance_traveled(2,1) is 800 the GUI will take the sum of the first column (which is 900+800+0+0) and write it in a static test and the same thing should happen with the other column.
This should continue until t = 4 i.e. until it does the same thing for each column, then it should reset.
I hope, I have explained my problem better this time and I apologize for my bad English.
I appreciate any help.
Based on your code fragment the for loop is only called once.
However, the contents of the for loop are ran for four times. (first for i=1 then for 1=2 etc..)
If you only want to run one of these options the solution is very simple:
i = 1
yourLoopContent
If i is always 0 the first time, and you always want to run it for the current i, it would also be simple:
yourLoopContent
i = i+1;
However if i may not be set properly the first time, things get messy. This is because i is by default defined as the square root of minus 1.
Therefore I would recommend you to use a different letter like t instead. Then you could do this:
if ~exists(t)
t=0;
end
yourLoopContent %Everywhere using t instead of i
t = t+1;
In general you may want to avoid i as an index to stay clear of complex number issues.
I'm not sure if I got your question correctly, but it seems to me that what you look for is a cumulative sum. This can be done either buy summing on 1:t or by using cumsum. I'm not sure why you use a loop, but if this is only for the summing then cumsum can replace that.
Here is some example in your code:
total_Route = zeros(4,4);
% I commented below what is not part of the question
for t = 1:4
total_Route(t,:) = [Distance_Traveled_CM,
Hauptantrieb_Verbrauchte_Energie_CM,
Nebenaggregate_Verbrauch_Real_CM,
t];
% the following line compute the comulative sum from the top of each
% column to every element in it, so cs_total_Route(3,2) is like
% sum(total_Route(1:3,2)):
cs_total_Route = cumsum(total_Route);
Total_Distance_Traveled_CM = cs_total_Route(t,1); % OR sum(total_Route(1:t,1))
% set(handles.edit3, 'string',Total_Distance_Traveled_CM);
Total_Hauptantrieb_Verbrauchte_Energie_CM = cs_total_Route(t,2); % OR sum(total_Route(1:t,2))
% set(handles.edit4, 'string',Total_Hauptantrieb_Verbrauchte_Energie_CM);
Total_Nebenaggregate_Verbrauch_Real_CM = cs_total_Route(t,3); % OR sum(total_Route(1:t,3))
% set(handles.edit5, 'string',Total_Nebenaggregate_Verbrauch_Real_CM);
% set(handles.edit15, 'string',t);
end
And here is a quick look on what cumsum does (with some random numbers for total_Route):
total_Route =
671 4.6012 1.0662 1
840 3.6475 0.58918 2
354 8.6056 2.1313 3
893 4.1362 2.0118 4
cs_total_Route =
671 4.6012 1.0662 1
1511 8.2487 1.6554 3
1865 16.854 3.7867 6
2758 20.991 5.7985 10
Is this what you looked for?

Matlab programming code

I wrote a program on Matlab that checks how many numbers are divisable by 2 starting from 1 to integer N (that is set by the user)
Here's my code:
num=input('Please enter a number');
count=0;
while (num>=0);
if mod(num,2)==0;
count=count+1;
end
num=num-1;
end
disp(count)
I've tried to run this code but it doesn't output anything. I hope someone can help me figure out what is wrong it Please note that we haven't studied it in school, I just read online and tried to write something on my own.
I see many logical errors in your code. To begin with you are checking if num is divisible by 10, not 2. Also you should decrement num regardless if it passes the if condition, if you want to check the next number. Finally you say you want to check numbers ranging 1 to N but your while loop actually checks numbers 0 to N, due to the >= condition.
From a syntactical point of view: if's and while's (and for's) should not have a trailing semicolon after them.
So maybe something like this could be closer to what you are asking, albeit I still don't know if I fully understand your problem.
% Ask for user input
num = input('Please enter a number');
count = 0;
while (num > 0)
% Check for divisibility
if mod (num, 2) == 0
count = count + 1;
end
% Decrement number
num = num - 1;
end
% Display the count -- writing the variable name without an ending semicolon ';' causes Matlab to output the variable content
count
No need in loop, use Matlab the way it was designed for
num = input('Please enter a number ');
count = sum(mod(1 : num, 2) == 0);
disp(count);

Whats wrong with my function code (MATLAB/OCTAVE)

I am trying to make my program work. It is for prime numbers.
Below is my function then my main program
I believe this is the right formatting, (obviously I'm probably wrong cause its not working) and I have been trying to fix it to no avail. Any help will be most appreciated and an explanation of what I am doing wrong (I am pretty sure it has to do with subtle formatting) would be great too.
function [answer,primefactors ] = primey1 (N)
for i=2:(N-1)
A(i-1)=rem(N,i);
end
A;
if(all(A)==1)
answer=['Yes']
primefactors=[1,N]
elseif(all(A)==0)
answer=['No']
fac=[]
for i=2:N
q=0;
while N/i==floor(N/i)
N=N/i;
q=q+1;
end
if q>0
fac=[fac,i]
if N==1
break
primefactors=[fac]
end
end
end
end
endfunction
As noted by Magla, MATLAB comes with the primes and factor functions, which you can at least use to compare your implementation with and/or check your outcomes.
Anyway, as for your code, try this:
function [answer, primefactors] = primey1(N)
% Use vectorization for simple cases such as these:
A = rem(N,2:N-1);
if all(A)
answer = 'Yes';
primefactors = [1,N];
% Re-wrote this entire section. There were a bunch of things wrong with it:
% the order of commands was wrong, variables were not assigned for some N,
% etc. Just compare the two implementations
else
answer = 'No';
primefactors = [];
for ii = 2:N
q = 0;
while N/ii == floor(N/ii)
N = N/ii;
q = q+1;
end
if q > 0
primefactors = [primefactors,ii]; %#ok<AGROW>
if N==1
break;
end
end
end
end
end
Matlab has a factor function that does what your code is trying to do
p = factor(10)
returns 2, 5
and
p = factor(11)
returns 11.
All you have is to test for length
if length(p) == 1
is true for prime numbers.
The solution as offered by #Rody should do the job, in theory even more efficient than this, however to illustrate the concept of initialization, I would recommend you to initialize the output variables of your function right after the function start. In your case this would mean that I recommend starting the code like this:
function [answer, primefactors] = primey1(N)
% Function to determine whether a number is prime and which prime factors it has
% Assign default values
answer = 'No';
primefactors = [];

Sudoku Solver, small snippet issue (matlab)

For this little snippet, I am generating a random number, checking if it is part of the row and column, if it's not part of either, it inserts the number. I know it might put a number that is already in its 3x3 box, but that's a problem I can fix. Here's my snippet, if want my whole code I will edit. My whole code is around 100 lines.
% Find empty slots, generate random number 1 - 9, insert into slot.
for i=1:9
for j=1:9
number = board(i,j);
answer = ceil(9*rand(1,1));
row = board(i,:);
col = board(:,j);
if number==0 && (ismember(answer,row)==0) && (ismember(answer,col)==0)
board(i,j) = answer;
end
end
end
My problem, is when I ran this with a real unsolved puzzle, is
1) It inserted an 11 into a slot, how is that possible?
2) I still see rows and columns where there are more than one of the same number.
Thank you guys.
I don't know why your bit of code would result in duplicates on rows or columns and why you would see 11's, so this might not exactly be an answer to your question, but it might help you. I modified your code a bit, to not only try one random number, but try all numbers 1-9 (in random order):
for i=1:9
for j=1:9
tried = [];
while board(i,j)==0
newRand = 0;
while ~newRand
answer = ceil(9*rand);
if ~ismember(answer,tried)
newRand = 1;
end
end
row = board(i,:);
col = board(:,j);
if (ismember(answer,row)==0) && (ismember(answer,col)==0)
board(i,j) = answer;
else
tried = [tried answer];
if length(tried)==9
break;
end
end
end
end
end

How to check a matrix is/isn't in an array (Matlab)

I have an array (M) of matrices. I perform an operation on the matrix in the ith position, and it adds three more matrices to my array in the (3i-1), (3i) and (3i+1)th positions. I want to continue this process until I reach the jth position in the array, where j is such that all matrices in the (j+1)th position and onwards have appeared already somewhere between positions 1 and j (inclusive).
EDIT: I've been asked to clarify what I mean. I am unable to write code that makes my algorithm terminate when I want it to as explained above. If I knew a proper way of searching through an array of matrices to check if a given matrix is contained, then I could do it. I tried the following:
done = 0;
ii = 1
while done ~= 1
%operation on matrix in ith position omitted, but this is where it goes
for jj = ii+1:numel(M)
for kk = 1:ii
if M{jj} == M{kk};
done = done + 1/(numel(M) - ii);
break
end
end
end
if done ~= 1
done = 0;
end
ii = ii + 1
end
The problem I have with this (as I'm sure you can see) is that if the process goes on for too long, rounding errors stop ever allowing done = 1, and the algorithm doesn't terminate. I tried getting round this by introducing thresholds, something like
while abs(done - 1) > thresh
and
if abs(done - 1) > thresh
done = 0;
end
This makes the algorithm work more often, but I don't have a 'one size fits all' threshold that I could use (the process could continue for arbitrarily many steps), so it still ends up breaking.
What can I do to fix this?
Thanks
Why don't you initialize done at 0, keep your while done==0 loop, and instead of computing done as a sum of elements, check if your condition (finding if the matrix already exists) is verified for all jj, something like this:
alldone=zeros(numel(M)-ii,1);
for jj = ii+1:numel(M)
for kk = 1:ii
if isequal(M{jj},M{kk})
alldone(jj-ii) = 1
break
end
end
end
done=prod(alldone);
There is probably a more elegant way to code this, though.
For instance, you could add early termination:
while done==0
done=1;
for jj = ii+1:numel(M)
match_success=0;
for kk = 1:ii
if isequal(M{jj},M{kk})
match_success=1;
break
end
end
if match_success==0
done=0;
break;
end
end
end
At the beginning of each loop, the algorithm assumes it is going to succeed and stop there (hence the done=1). Then for each jj, we create a match_success which will be set to 1 only if a match is found for M{jj}. If the match is found, we break and go to the next j. If no match if found for j, match_success is left to 0, done is initialized to 0 and the while loop continues. I haven't checked it, but I think it should work.
This is just a simple tweak, but again, more thought can probably speed up this whole code a lot.