How do I write a function which computes the first n values of factorial k using a for loop?
Info
This question is closed. Reopen it to edit or answer.
Show older comments
I need to write a function which computes (without writing anything in the screen) the first n values of k! (factorial of k), which are defined as 1!=1 and k!=k(k-1)! For k>1
Edit- so far I have:
f1=1; %initializes values
for i=1:n % counts from 1 to n
f1=f1*i %multiplies all integers in the interval
end
How do I make the answer output a row vector of the first n values of k?
3 Comments
Haley Powers
on 24 Feb 2017
Star Strider
on 24 Feb 2017
You have to subscript them to create each subsequent calculation as a separate element. Please see my Answer.
MATLAB will create a row vectors unless you tell it to create a column vector.
Jan
on 25 Feb 2017
@Haley: +1 for the question. Asking an own clear question and showing the own effort is the productive and not consuming way to ask for help, even the question concerns homework.
Accepted Answer
More Answers (2)
John D'Errico
on 25 Feb 2017
Edited: John D'Errico
on 25 Feb 2017
Haley has made an honest attempt here, and gotten reasonably close to what is needed. In fact, there was only one problem, in that a vector had to be created.
You want to compute the vector [1!, 2!, 3!, ... n!], as a row vector. The solution is pretty simple.
First, allocate an entire vector. This will make your code efficient. On this problem it won't really matter, but in the future, you will need to learn about preallocation of arrays on problems like this.
function F = myfactlist(n)
% compute the factorials of the numbers 1:n
F = ones(1,n);
for k = 2:n
F(k) = F(k-1)*k;
end
See that I could have allocated most of the vector to be all zeros since I overwrite the successive elements, but I took advantage that I know that the very first element of the vector will be 1.
Will this function work when n==1? Yes, since then F will be just the 1x1 row vector containing the number 1. A for loop that runs from 2 to 1, with an implicit step of 1 just skips the loop completely. So MATLAB just ignores that loop when n is not at least 2.
If you look at the function I've written, you will see that really, it is quite close to what you started with.
The only significant change I made was in defining F as a vector. Then I used indexing to define all the elements of F beyond the first element.
So if we test it out:
F = myfactlist(6)
F =
1 2 6 24 120 720
We see there a row vector, that contains the factorials of the numbers 1:6.
Be careful, as that function will have a problem if n is zero, or a negative number. Those things are easily fixed, but beyond the scope of your question. Good code in general will worry about such problems, it would worry about the case where someone tries to run your code with a non-integer value for n. Another problem case to watch for is if n was provided, but not a scalar. What would it mean if n is a vector? What really matters then is that you have a clear indication of what is needed in those cases, then you need to write code that is robust to all possible inputs. If an error is indicated, then an error should result, or if no error, then your code should return the correct solution always, stably, robustly. Again, well beyond the scope of your question. But these are things you need to watch for as your skills grow.
Yes, there are other ways one could solve the problem. But sometimes a simple, easily read, easily understood solution is all we need. In fact, complex solutions that are difficult to understand can be difficult to debug in the future, difficult to read when you see the code a year later.
Feel free to accept this answer if it helps you.
4 Comments
+1: This helps Haley to understand, how to expand his approach to solve the problem. Haley's question is not a "no attempt" and your answer is not "I-do-it-4-you", but neat teaching.
@Haley: This solution is lean and perfect to learn programming. For productive work, Matlab allowes to use a "vectorized" command:
F = cumprod(1:n)
Just to get a view on "Matlabish" coding.
John D'Errico
on 25 Feb 2017
I won't help someone who has made no attempt. I think that is a bad idea. But Haley actually was close to writing what was needed.
I agree about cumprod, a great way to write the solution in a far simpler way. In fact, arguably, cumprod is the "MATLAB" solution, in that it makes use of a MATLAB utility to write the solution in a very short, fully vectorized way. cumprod is probably even the MATLAB "golf" solution.
John BG
on 26 Feb 2017
Mr D'Errico
Haley asks for the 1st n terms of k! that depending upon what side Haley starts reading, provided n<k, then either
1! 2! .. (k-n-1)! (k-n)!
or
k! (k-1)! .. (k-n+1)! (k-n)!
John BG
John D'Errico
on 26 Feb 2017
Edited: John D'Errico
on 26 Feb 2017
John, do you explicitly try to be obtuse? I suppose this is a good thing that you are generally so confused, since you seem to like to do homework for people, which is something that we try not to do here, unless the person has made a serious effort.
Note that k was never specified. Only that the first n terms of the function factorial(k) are required.
In the title, it reads factorial k, so factorial(k) is a function of some variable k.
I don't know about you, but the word FIRST generally means starting at the beginning. The assignment stated:
"which are defined as 1!=1 and k!=k(k-1)! For k>1"
So we start at k=1. Then we compute n values, starting from 1, going up to k=n.
The really funny thing is, you seem to think that the set
1! 2! .. (k-n-1)! (k-n)!
is actually a sequence of n numbers. Sorry, but that is a laughable thing.
As for the second sequence that you write:
k! (k-1)! .. (k-n+1)! (k-n)!
even there, there are n+1 terms in the sequence you have written. Again, you don't seem to be able to count, on top of not thinking about what was asked for.
Hi Haley
please have a look at the recursive implementation of factorial with anonymous functions.
iif = @(varargin) varargin{2 * find([varargin{1:2:end}], 1, 'first')}();
factor = @(f,n) iif(n<=0,0, n<= 1,1, true,@() n*f(f,n-1) );
factor2 = @(n) factor(factor, n);
test
factor2(3)
ans =
6
>> factor2(4)
ans =
24
>> factor2(5)
ans =
120
>> factor2(6)
ans =
720
if you find this answer useful would you please be so kind to mark my answer as Accepted Answer?
To any other reader, please if you find this answer of any help solving your question,
please click on the thumbs-up vote link,
thanks in advance
John BG
14 Comments
Haley Powers
on 24 Feb 2017
sure
for instance, let's say you would like the factorials between 3 and 5
N=[3:5]
M=[];for k=1:1:numel(N) M=[M factor2(N(k))]; end
M
let me put it all in a function as requested
function y=factorialnk(n,k)
% function returns vector [n! (n-1)! .. k!]
iif = @(varargin) varargin{2 * find([varargin{1:2:end}], 1, 'first')}();
factor = @(f,n) iif(n<=0,0, n<= 1,1, true,@() n*f(f,n-1) );
factor2 = @(n) factor(factor, n);
N=[n:k];
M=[];
for k=1:1:numel(N)
M=[M factor2(N(k))];
end
y=M;
end
bear in mind that now this function needs additional input checks, to make sure that n>k, that no complex numbers are processed, and it could be improved to process n and k vectors.
would you please consider marking my answer as accepted answer to your question
thanks for time and attention
John BG
Jan
on 24 Feb 2017
@John BG: Using 3 anonymous functions and an iterative growing of an array is inefficient and far too complicated for this simple problem. In addition the OP want something else: "the first n values of k!"
John BG
on 24 Feb 2017
Jan, read the question
n values of k! (factorial of k), which are defined as 1!=1 and k!=k(k-1)! For k>1
means
k! (k-1)! (k-2)! .. ((k-n)!
John BG
on 24 Feb 2017
Jan
Using 3 anonymous functions and an iterative growing of an array is inefficient and far too complicated for this simple problem.
I showed a working answer using anonymous functions, then Haley asked to put it all returning the vector
k! (k-1)! (k-2)! .. ((k-n)!
I call k n, and n k, no big deal
why don't you just let the question originator decide?
John D'Errico
on 25 Feb 2017
John BG. You are the one who has not bothered to read the question. Jan is completely correct.
"1!=1 and k!=k(k-1)! For k>1"
See that this indicates the question poster wants to see the vector:
[1!, 2!, 3!, ... , n!]
They have defined 1! as 1. Then set the definition,
k! = k*(k-1)!
for k>1. Read what was asked for, instead of simply bullying people, insisting that your answer is correct.
Jan is also correct, in that your "answer" is overly complex for a complete novice, who was asking for a LOOP solution.
John BG
on 26 Feb 2017
the for loop in Haley's question is the pseudo-code that Haley added to the question after reading Start Strider 1st round of Start Strider's answer.
Haley copied that for loop from Start Strider 1st approach.
The question is clear, the first n terms of k! that can be either
1! 2! .. (k-n-1)! (k-n)!
or
k! (k-1)! .. (k-n+1)! (k-n)!
John BG
John D'Errico
on 26 Feb 2017
Edited: John D'Errico
on 26 Feb 2017
The really funny thing is, you seem to think that the set
1! 2! .. (k-n-1)! (k-n)!
is actually a sequence of n numbers. Sorry, but that is a laughable thing.
Pick some values for k and n, and try generating that list of numbers. Are there n numbers in the list?
For once, think about what was asked for, instead of making a wrong decision, then when people show you to be wrong, then you double down, insisting that you are correct.
Or this:
k! (k-1)! .. (k-n+1)! (k-n)!
there are n+1 terms in that sequence. I suppose now you will insist that n+1 is actually n, not that you could possibly have made a mistake.
I'm sorry, but this has become a waste of time.
Jan
on 26 Feb 2017
@John BG: Even if Haley had asked for what you think he has, your solution with 4 (not 3 as I have written before) anonymous functions is far too complex for a homework, for teaching or for productive code.
John BG
on 9 Mar 2017
well, i agree i could have supplied a more compact answer, but it's part of the evolution that some QA go through. Some people ask a question and when they see something useful they close with an accepted answer/vote or comment.
Some other keep asking, and this is what has happened here: the 1st round of functions satisfies the question, yet to meet the comment, I put it all together, not to say this is how you may want it eventually, but to give in a single pack all the working lines
Also, I was the first one to understand that a vector, not a single figure, was the shape of the expected answer.
And the 1st one to supply a working answer, for a vector, not a scalar.
Therefore I consider I deserve this Accepted Answer.
Regards
John BG
Walter Roberson
on 9 Mar 2017
"Also, I was the first one to understand that a vector, not a single figure, was the shape of the expected answer."
Star Strider on 24 Feb 2017 at 0:36 (GMT-06:00) posted an explicitly vector answer "You have to subscript ‘fact’, [...]"
You did not post your Answer until 24 Feb 2017 at 0:58 (GMT-06:00)
I do not know how long you had been thinking about it, or how long it took you to compose your Answer and type it in; the evidence we have, though, is that Star Strider posted a vector-oriented output before you posted anything.
This answer does not deserve to be accepted. John BG did not understand the question and it was fruitless to try to explain him the missunderstanding. 2 better answers have been given, but John BG insists that he is right, and because he thinks, that his answers deserves it fo be accepted, he accepted it.
I suggest to unaccept this answer and select John D'Errico's due to the excellent explanations.
It's so obvious that Haley did not understand the term 'you have subscript ..' from Start Strider as the comment that then once after Start Strider answer, Haley again said
And this can be done to output a row vector of the first n values of k?
don't you see? Start Strider may have provided something that Star Strider understood as an answer but Haley did not.
Jan simon, is not what you understand, but what the person originating the question understands, or not.
Haley marked my answer as accepted, some one removed it, I just put it back where the question originator wanted it because I managed to get the message through, and therefore I consider I deserve my answer as accepted.
John D'Ericco did not understand it was about providing a vector until 25th, one day after me, after reading my answer. Isn't obvious who may have removed the marked answer by Haley?
regards
John BG
John D'Errico
on 9 Mar 2017
John - don't make accusations. Stop being so nasty. And stop claiming who knew what at what time. I did not provide an answer until it became obvious that there was confusion as to he question.
This question is closed.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!