So I need to output a sum of factorials like 1!+2!...+n!=sum I found a way to get a single factorial but I don't know how to sum them together. This is my attempt at doing so:
System.out.println("Ievadiet ciparu");
Scanner in = new Scanner(System.in);
n = in.nextInt();
if ( n < 0 )
System.out.println("Ciparam jabut pozitivam.");
else
{
while (x>2){
for ( c = 1 ; c <= n ; c++ )
fact = fact*c;
sum=sum+fact;
n=n-1;
if (n==0) break;
}
System.out.println("Faktorialu summa "+sum);
Rather than have a loop 1-n and calculate each factorial elsewhere, I would accumulate the sum as you calculate the factorials - ie have two local variables; one for factorial and one for the sum:
long factorial = 1, sum = 0;
for (int i = 1; i <= n; i++) {
factorial *= i;
sum += factorial;
}
When tested with n = 5, sum is 153, which is correct: 1 + 2 + 6 + 24 + 120
Your problem was that the sum was outside the loop - you just needed braces like here.
Also, your while loop condition x < 2 will never change, so either the loop will never execute (if x > 1) or the loop will never terminate, because x is not changed within the loop.
hmmm my search for finding a recursive(via recursive method calling) version of these code still getting nowhere
`public static long factorialSum(long n){
long x = n;
for(int i = 1; i < n; i++){
x = (n-i)*(1+x);
}
return x;
}`
if you just look at the problem more closely you'll see you can do it in linear time, the trick is in (n-1)! + n! = (n-1)!*(1 + n), to understand this more deeply i recommend add (n-2)! just to see how it grows.
Related
I have this code from my computer science class:
int input=15;
while (input < n ) { input = input *3;}
This code has the ceiling of log3(n/15) loops. How can we obtain this result?
I think he is talking about the analytical solution to complexity. I think it's something like this (long time ago i did logaritms):
15 * 3^x = n // x would be the number of iterations until value reaches n
ln(15*(3^x)) = ln(n)
ln(15) + ln(3^x) = ln(n)
ln(15) + x*ln(3) = ln(n)
x = (ln(n) - ln(15)) / ln(3)
x = ln(n/15) / ln(3)
x = log3(n/15) / log3(3)
x = log3(n/15)
For what values of n does the code loop k times?
It must be that 15 < n, and 15*3 < n and 15*3*3 < n and .... and 15*3^(k-1) < n. Also, it must be that 15*3^k >= n (otherwise the code would do at least one more loop).
That is, 3^k >= n/15 > 3^(k-1), and taking logs (base 3), k >= log3(n/15) > k-1.
Thus k is the smallest integer greater than or equal to log3(n/15), or equivalently: k = ceil(log3(n/15)) as required.
I am trying to figure out what the time complexity of this simple program is, but I can't seem to understand what would be the best way to do this.
I have written down the time complexity side by side for each line
1 public int fnA (int n) {
2 int sum = 0; O(1)
3 for (int i = 0; i < n; i++) { O(n)
4 int j = i; O(n)
5 int product = 1; O(1)
6
7 while (j > 1) { O(n)
8 product ∗= j; O(log n)
9 j = j / 2; O(log n)
10 }
11 sum += product; O(1)
12 }
13 return sum; O(1)
14 }
Am I correct to assume these running times and that the final running time is: O(n)
If not, would somebody be able to explain where it is I am going wrong?
Overall:
1 + n + n + 1 + n + logn + logn + 1 + 1
= 3n + 2logn + 4
Final: O(n)
Time complexity for that algorithm is O(NlogN).
The for loop is executed N times (from 0 to N).
The while loop is executed logN times since your are dividing the number to half each time.
Since your are executing the while inside the for, your are executing a logN operation N times, from there it is the O(NlogN).
All remaining operations (assign, multiplication, division, sum) you can assume that takes O(1)
The crux of the above program is the while loop and it is the defining factor and rest of the lines will not have complexity more than O(n) and assuming that arithmetic operations will run in O(1) time.
while (j > 1) {
product ∗= j;
j = j / 2;
}
The above loop will have a run time of O(log(j)) and j is varying from 1 to n, so its the series...
-> O(log(1) + log(2) + log(3) + log(4).....log(n))
-> O(log(1*2*3*4...*n))
-> O(log(n!))
and O(log(n!)) is equal to O(n log(n))
For the proof for above refer this
No for every i, there is logn loop running and hence for n elements the total complexity is nlogn.
Since you know that the following loop takes logn .
while (j > 1) {
product ∗= j;
j = j / 2;
}
Now this particular loop is executed for every i. And so this will be executed n times. So it becomes nlogn.
To start with, you could count all operations. For example:
1 public int fnA (int n) {
2 int sum = 0; 1
3 for (int i = 0; i < n; i++) {
4 int j = i; n
5 int product = 1; n
6
7 while (j > 1) {
8 product ∗= j; ?
9 j = j / 2; ?
10 }
11 sum += product; n
12 }
13 return sum; 1
14 }
Now we could do the counting: which sums up to: 2 + 3n + nlog(n)
In a lot of programs the counting is more complex and usually has one outstanding higher order term, for example: 2+3n+2n2. When talking about performance we really care about when n is large, because when n is small, the sum is small anyway. When n is large, higher order term drawf the rest, so in this example 2n2 is really the term that matters. So that's the concept of tilde approximation.
With that in mind, usually one could quickly identify the portion of code that gets executed most often and use its count to represent overall time complexity. In example given by OP, it would look like this:
for (int i = 0; i < n; i++) {
for (int j = i; j > 1; j /= 2)
product *= j;
}
which gives ∑log2n. Usually the counting involves discrete mathamatics, one trick I have learned is to just replace with it integral and do caculus: ∫ log2n = nlog(n)
Today I practiced for my coding test using projecteulers problems. While doing the prime factor division I stumbled across something I found weird. Here is the relevant code (res is an ArrayList):
for (int x = 2; x <= n; x++){
if (n % x == 0){
System.out.println("Prime found: " + x);
res.add(x);
n = n / x;
}
}
Which divided 1000 into [2, 4, 5, 25].
After a while I tried replacing the if-statement with a while-loop and it printed me the correct answer [2, 2, 2, 5, 5, 5].
Obviously there is somthing I didn't understand, could someone explain this to me, please?
Edit:
The newer code:
for (int x = 2; x <= n; x++){
while (n % x == 0){
System.out.println("Prime found: " + x);
res.add(x);
n = n / x;
}
}
The difference is:
If you use if, every number is tested only once. So if you are able to pull out the 2, you try so only once. The next number you can pull out is the 4, although it is not a prime.
The same holds for the 5 resp. 25.
If you use while, you test each number until you know it's no longer in the number to test.
You could also change it into
for (int x = 2 ; x <= n/x ; ) {
if (n % x == 0) {
System.out.println("Prime factor: " + x);
res.add(x);
n = n / x;
}
else {
x++; // increment moved here
}
}
if (n > 1) {
System.out.println("Prime factor: " + n);
res.add(n);
}
I've also changed the termination condition, to make it much more efficient in cases where n's largest prime factor is itself large, because if n = a*b and a <= b, then a*a <= a*b = n, i.e. a <= n/a.
This repeats the test for a prime factor, because as you've found out, some numbers have multiple prime factors of same magnitude (like 1000 = 2*2*2*5*5*5). It is equivalent to your while loop, because the increment is now conditional, performed only when the tested candidate was not n's factor.
I'm trying to find the factorial of 9 down to 0, only using one while loop, but my idea isn't outputting a value.
I figured out the way to do it using two while loops:
int i;
count = 9;
while (count >= 0){
value = count;
i = count-1;
while (i > 0){
value = value * i;
i--;
}
System.out.print(value + ", ");
}
This worked but I've tried to change it to use only one while loop and got this:
int i;
for (count = 9; count < 0; count--){
value = count;
i = count-1;
while (i > 0){
value = value * i;
i--;
}
System.out.print(value + ", ");
}
I'm not completely sure if I'm using the for statement correctly but I think I am, or at least I think it should output something so I can debug it.
Could someone give me a hint in the right direction?
This will give you all the factorials from 9 down to 1 :
int i=1;
int value=1;
String res = "";
while (i <= 9){
value = value * i;
res = value + ((i>1)?",":"") + res;
i++;
}
System.out.print(res);
Output :
362880,40320,5040,720,120,24,6,2,1
Perhaps it's cheating, since I'm calculating the factorials in ascending order from 1! to 9!, but I'm reversing the order of the output in order to get the required result.
Edit :
If you also want 0! to be printed, a small change can do the trick :
int i=1;
int value=1;
String res = "";
while (i <= 10){
res = value + ((i>1)?",":"") + res;
value = value * i;
i++;
}
System.out.print(res);
Output :
362880,40320,5040,720,120,24,6,2,1,1
First, the reason why your second loop doesn't work is that you have the wrong condition in the for. The condition in the middle is one that will cause the loop to continue, not to stop. So what you were saying was "start from 9, and work while the number is less than 0". But of course, your number is greater than zero to begin with.
Second, I believe using a for loop is a little bit of cheating, because a for loop is just a specific case of while loop.
Now to the problem of the factorial itself. You know that a factorial n! is defined as (n-1)!*n.
The basic loop for calculating one specific factorial is:
int n = 5;
int factorial = 1;
while ( n > 0 ) {
factorial *= n;
n--;
}
System.out.println( "Factorial is: " + factorial );
This will give you the factorial of five. But it's not exactly based on the formula we are talking about. There is another way to calculate it, starting from 1:
int n = 5;
int factorial = 1;
int count = 1;
while ( count <= n ) {
factorial *= count;
count++;
}
System.out.println( "Factorial is " + factorial );
The interesting part about this way of doing it is that in every stage of the loop, factorial is actually the value (count-1)! and we are multiplying it by count. This is exactly the formula we were talking about.
And the good thing about it is that just before you did it, you had the value of the previous factorial. So if you printed it then, there you'd get a list of all the factorials along the way. So here is a modified loop that prints all the factorials.
int n = 9;
int factorial = 1;
int count = 0;
while ( count < n ) {
System.out.println( "Factorial of " + count + " is " + factorial );
count++;
factorial *= count;
}
System.out.println( "Factorial of " + n + " is " + factorial );
Note that I modified it a little more so that it will work with zero. The factorial of zero is a special case so we shouldn't multiply by zero - that will make all the factorials wrong. So I changed the loop to multiply only after I increase count to 1. But this also means that you have to print the final factorial out of the loop.
Just first assign value=i, then run your loop. You can get the factorial with only while loop.
Important: Because n!=n*(n-1)!, therefore, i-- should must be perform before value = value * i.
public static void main(String args[]) {
int value=5;
int i=value;
while (i > 1){
i--;
value = value * i;
}
System.out.print(value);
}
Update: If you want to count factorial of 0 to 9, then use this code: (It includes factorial of 0 also)
public static void main(String args[]){
int countLowest=0;
int countHighest=9;
int value=1;
while (countLowest<= countHighest){
if(countLowest==0)
value = value * (countLowest+1);
else
value=value*countLowest;
countLowest++;
System.out.println("Factorial of "+(countLowest-1)+" is "+value);
}
}
Result:
Factorial of 0 is 1
Factorial of 1 is 1
Factorial of 2 is 2
Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 5 is 120
Factorial of 6 is 720
Factorial of 7 is 5040
Factorial of 8 is 40320
Factorial of 9 is 362880
count = 9;
sum=1;
while (count >= 1){
sum*=count;
--count;
}
System.out.print(sum);
it will give you 9!=362880
I want this while loop to print every multiple of two below the number submitted(ex. if 100 was submitted it would print 2 4 8 16 32 64). Here's what I have(I'm only going to include a portion of the class because there was other things in it that don't pertain to this part)
i = 1;
Scanner myScanner = new Scanner(System.in);
System.out.print("Would thoughst be inclined to enter a number fair sir/madam: ");
String answer = myScanner.nextLine();
int number = Integer.parseInt(answer);
System.out.print("Your number set is: ");
while(i <= number)
{
i = 2*i;
System.out.print(" " + i + " ");
}
What this prints if I enter 100 is: 2 4 8 16 32 64 128
How do I get rid of that last number?
You would get rid of that number by modifying your logic to match. Your code is doing precisely what it says. One option is to start at 2, and increase i at the end of the loop instead of just before printing it. You could also use a for loop:
for (int i = 2; i < 100; i *= 2)
...
If you want to save the last power, you have a few options, e.g.:
int k = 2;
for (int i = k; i < 100; i *= 2) {
k = i;
...
}
Or undo the last operation:
int i;
for (i = 2; i < 100; i *= 2)
...;
i /= 2;
Or check the next one:
int i;
for (i = 2; i * 2 < 100; i *= 2)
...;
Checking the next one, in your original form:
while (i * 2 <= number)
...;
Etc.
By the way, your title says "factors", your description says "multiples", and your code says "powers"...
In your code
while(i <= number)
{
i = 2*i;
System.out.print(" " + i + " ");
}
the problem is that i, when it is equal to 64, is indeed less than 100, so the loop continues.
If you change it to
i = 2*i;
while(i <= number)
{
System.out.print(" " + i + " ");
i = 2*i;
}
it does as you wish, because it pre-computes the value before being analyzed as the while-loop terminator.
Try
while( i <= number / 2)
Those are powers of 2, not factors of 2.
"thoughst" is not a word. It should be "thou".
Update the value of i after you print it.