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);
Related
This is my attempt of a simple example (it seems pointless) but the idea is bigger than this simple code.
During a for loop, if something happens, I want to skip this step of the for loop and then add an extra step on the end.
I am trying to create a list of numbers, that do not include the number 8.
If the code creates an 8, this will mean that exitflag is equal to 1.
Can I adapt this program so that if the exitflag=1, the it will remove that result and add another loop.
The code:
for i = 1:1000
j = 1+round(rand*10)
if j == 8
exitflag = 1
else
exitflag = 0
end
storeexit(i)=exitflag;
storej(i)=j;
end
sum(storeexit)
I would ideally like a list of numbers, 1000 long which does not contain an 8.
If what you want to do is 1000 iterations of the loop, but repeat a loop iteration if you don't like its result, instead of tagging the repeat at the end, what you can do is loop inside the for loop until you do like the result of that iteration:
stores = zeros(1000,1); % Note that it is important to preallocate arrays, even in toy examples :)
for i = 1:1000
success = false; % MATLAB has no do..while loop, this is slightly more awkward....
while ~success
j = 1+round(rand*10);
success = j ~= 8;
end
storej(i) = j; % j guaranteed to not be 8
end
No.
With for loop, the number of loops is determined on the loop start and it is not dynamic.
For doing what you want, you need to use a while loop.
I have difficulty in writing an algortihm that takes three numbers as input from the user and calculates the maximum of them. I'm trying to do these by using function, however, I get an error message: "Undefined function 'calc' for input arguments of type 'char'.
Error in Untitled (line 2) calc(numbers); "
Here's my code: (I'm new at coding so there may be other types of errors:))
numbers= input('Enter three numbers to find out maximum of them:','s');
calc(numbers);
maxi
function [ maxi ] = calc( numbers(1),numbers(2),numbers(3) )
%UNTÄ°TLED2 Summary of this function goes here
% Detailed explanation goes here
maxi= numbers(1);
if numbers(2)>maxi
maxi= numbers(2)
end
if numbers(3)>maxi
maxi= numbers(3)
end
end
As you say that "I'm new at coding", I thought I'd describe a couple of different approaches for this.
Reading the input
You could do as H.Ghassami suggests and read the input one by one.
This is probably the better option as there is some fault handling
built into it. The user can only enter one input at a time and there
is check that the inputs is evaluable (a number or a variable from
the current workspace). The rutin could get a little bit more general by adding a variable for the number of inputs to get.
numberOfInputs = 3;
number = zeros(1, numberOfInputs);
for idx = 1:numberOfInputs
% Get the number of inputs declared in numberOfInputs
number(idx) = input( sprintf('Enter number %d: ', idx));
end
You could also let the user enter all the numbers at once by, as the example in your question, add a 2nd argument 's' to input. The input is now treated as a string. The user has to separate the input numbers in some way, preferable with a whitespace. You then have to convert to string to a number vector.
numberOfInputs = 3;
number = input( sprintf('Enter %d numbers separated by whitespaces\n', numberOfInputs), 's');
number = str2num(number); % Convert to number array
You should probably do some check on the number array to see that it is valid (numbers of the correct amount)
Getting the max
Matlab has an buildin function for this. So you could just write
maxNumber= max(number);
or if you, perhaps for the exercise, would like to use an if structure you could make it more general with a for loop
maxNumber = number(1);
for idx = 2:numberOfInputs
if maxNumber < number(idx)
maxNumber = number(idx);
end
end
-
The entire solution could be encapsulated in a function
function maxNumber = getMaxInput(numberOfInputs)
Your first mistake is input . It just get just one string from user, but you need three numbers.
Second one is the next line in your script. When you calculate the numbers, you should send output to a variable. Also you should change the calc parameters.
Put this code in your script instead of your code :
number1= input('Enter number1:');
number2= input('Enter number2:');
number3= input('Enter number3:');
maxi=calc(number1,number2,number3)
%---------------------------------------------------
function [ maxi ] = calc( numbers1,numbers2,numbers3 )
%UNTÄ°TLED2 Summary of this function goes here
% Detailed explanation goes here
maxi= numbers1;
if numbers2>maxi
maxi= numbers2;
end
if numbers3>maxi
maxi= numbers3;
end
end
refrence to read for you: http://matlabgeeks.com/tips-tutorials/getting-user-input/
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 <
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
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.