To accept two numbers from the user and display perfect numbers between these two numbers. Can anyone help to convert this codes to somethings simpler to understand?? It's too complicated for me as i'm still new to matlab...
1 view (last 30 days)
Show older comments
clc % Clear Command Window
num1 =input('Enter num1 value: \n'); % Prompt and Get num1 input
num2 =input('Enter num2 value: \n'); % Prompt and Get num2 input
output = zeros(1,num2);
for i = num1:num2
if true
% code
end
test = 1:i-1;
if (sum(test(mod(i,test) == 0)) == i)
output(i) = i;
end
end
output(output == 0) = []
0 Comments
Answers (2)
Thorsten
on 20 Jan 2016
The if clause may be too tricky for a beginner:
(sum(test(mod(i,test) == 0)) == i)
Let's walk through it from the innermost parentheses to the outer. Recall the definition of a perfect number: Its divisors without the number itself sum up to the number.
So the first thing to do is to find all divisors of a number. This can be done using mod. mod(i,b) returns the remainder after dividing i by b. If a number is a divisor, the remainder is 0, so mod return zero. So to test if b is a divisor of i, use
mod(i,b) == 0
But we have to test not a single potential divisor b, but all potential numbers up to i-1. Why i-1? Because of the definition of a perfect number. All number from 1 to i-1 are coded as
1:i-1
These are our potential divisors, named 'test' in the code:
test = 1:i-1;
The nice thing about Matlab is the vectorized nature. Computing the remainder of dividing i by a vector test is as simple as
mod(i,test)
This return the remainders. We like to find the numbers in test where the remainders are zero:
mod(i, test) == 0
This gives a so called logical array of 0 and 1, (or false and true), with 1 at those positions where test is a divisor of i.
We can use the logical array as an index into test to get the divisors:
index = mod(i, test) == 0;
divisors = test(index);
or more concisely
divisors = test(mod(i, test) == 0)
So far, so good. The final step is to check whether the sum of all divisors
sum(divisors)
equals the number to test, i:
if sum(divisors) == i
In this case we have found a perfect number and store this number in a variable 'output' at the i'th position:
if sum(divisors) == i
output(i) = i;
end
We do this for all i between num1 and num2 using
for i = num1:num2
test = 1:i-1;
if sum(test(mod(i,test) == 0)) == i
output(i) = i;
end
end
The outer parentheses are not necessary, so I skipped them. After this loop we have the perfect numbers at the position of the perfect numbers. All other positions are zero, because we have initialized output this way.
The final step is now to get rid of the zeros in output using logical indexing again. In this case, all positions where output is 0 are replaced by the empty matrix [], so they are deleted:
output(output == 0) = [];
Et voilà!
0 Comments
Guillaume
on 20 Jan 2016
Edited: Guillaume
on 20 Jan 2016
Other than the extremely poor naming of variables and the lack of check that the user entered positive integer in the right order, this code is as simple as it can be.
Seriously, it's:
- a for loop generating a number between the input
- and an if check that the number is the sum of its divisors
That is all. If you want something different, why don't you give us the algorithm you wish to implement and we can give you some pointers on how to implement it.
The only thing I'd do to the code you've posted, other than adding checks on the user input is rename the i variable to potentialperfectnumber and test to potentialdivisor.
You could split the if statement in two to make it clearer what is going on:
potentialdivisors = 1:potentialperfectnumber-1; %was test = 1:i-1
divisors = potentialdivisors(mod(potentialperfectnumber, potentialdivisors) == 0); %was test(mod(i,test) == 0)
if sum(divisors) == potentialperfectnumber
%...
See Also
Categories
Find more on Time Series Events in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!