Doing a factorial with only one while loop - java

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

Related

Calculating how many times a number is added to itself until it reaches an arbitrary value?

Considering two variables:
"n" is any arbitrary value.
"i" is the number of times a value is increased in a sum before it reaches the value of "n".
So for instance if the value n = 344 is chosen, then i = 26 because:
26 + 25 + 24 + ... + 3 + 2 + 1 = 351
26 is how many times the variable "i" gets added together in a descending order before it either is equal to n = 344 or the first time it surpasses.
public class Trstuff{
public static void main (String [] arg) {
int n = 4;
int i = computeIndex(n);
System.out.print(i);
}
public static int computeIndex(int n) {
int i = 1;
int sum = 0;
for(i = 1; sum <= n; i++) {
sum = sum + i;
}
return i;
}
}
My goal is to choose any "n" value and then have the program return the variable "i" to me.
As my program stands, I thought it should be correct, but somehow it's not. Here is the example with n = 4.
The result should be that "i = 3" because:
1 + 2 = 3
1 + 2 + 3 = 6
So the ascending value of "i" in the loop is added 3 times before the loop supposedly should stop because of the expression "sum <= n" in the loop.
However, when I run the program it returns the value 4 instead. I simply cannot figure out what is wrong and why my program gives me 4 instead of the correct answer, 3?
Read the for loop as follows:
for every value of i while sum smaller or equal to n, add i to sum and increment i
The last part of the line and increment i is executed after the sum of sum + i, but before the next check which checks if sum is smaller or equal to n, with as result that i always is one larger than expected.
The solution could be to use a different exit (different solutions exist):
public static int computeIndex(int n) {
int i = 1;
int sum = 0;
while true {
sum = sum + i;
if sum<n {
i++;
} else break;
}
return i;
}
the sum of p consecutive integers starting at 1 is p*(p+1)/2
so basically you need to solve x^2+x-2*n = 0, with solution
x = 0.5*(sqrt(1+8n)-1)

Why sum of odd numbers from 1 to the number entered doesn't match what was expected?

import java.util.Scanner;
public class OddSum {
public static void main(String[] args) {
int num;
int i = 1;
int sum = 0;
Scanner input = new Scanner(System.in);
System.out.print("Enter a number: ");
num = input.nextInt();
input.close();
while (i<=num) {
i += 2;
sum +=i;
}
System.out.println("The sum of odd numbers between 1 and" + num + "is: " + sum);
}
}
I wrote this code to sum up the odd numbers from 1 to a number entered.
Now, when I entered 8, I got the output as 24, against the desired output 16.
Can you tell me what went wrong?
You are incrementing the variable before performing summation .
while (i<=num) {
sum +=i;
i += 2;
}
You should add i to sum before adding to 2 to i. Thus, once i goes past num, the while loop will no longer execute.
import java.util.Scanner;
public class OddSum {
public static void main(String[] args) {
int num;
int i = 1;
int sum = 0;
Scanner input = new Scanner(System.in);
System.out.print("Enter a number: ");
num = input.nextInt();
input.close();
while (i<=num) {
// add i to sum before adding 2 to i
sum += i;
i += 2;
}
System.out.println("The sum of odd numbers between 1 and" + num + "is: " + sum);
}
Lets debug the code together:
after taking the number it would go to i<=num that while condition. Great, Then instead of getting sum it would + again 2 which cause 3. So what's happen? First case, 1 is not added before and first iteration value 1 is lose. That means whenever, you enter the loop. It goes increases before adding the previous value. So, rewrite the code this way:
while (i<=num) {
sum +=i;
i += 2;
}
You may use for instead:
for(int i=1;i<=num;i+=2){
sum +=i;
}
You're incrementing i before you sum it, instead of afterwards:
while (i <= num) {
sum +=i;
i += 2;
}
It's worth noting, though, that these kind of issues, where the loop variable is incremented by a constant, are often more convenient to write with a for loop:
for (int i = 1; i <= num; i += 2) {
sum += i;
}
Or better yet, if you're using Java 8, by collecting a stream:
int sum = IntStream.rangeClosed(1, num).filter(i -> i % 2 != 0).sum();
The reason why the result for your example with N = 8 gives 24 is because when i reaches value 7, the loop is continued and is added the value 9 to your sum too and you forget to add the first odd number: 1, because you start over from adding directly 3 to your sum.
You can either switch the statements between each other, either use a for loop instead of while:
for(int i = 1; i <= num; i += 2) {
sum += i;
}

Same code gives different answer in C and Java, can you help me?

These snippets, respectively written in C and Java should output the same result, but they do not, and I'm not able to identify where's the bug.
written in C
#include <stdio.h>
/* discover and print all the multiples of 3 or 5
below 1000 */
int main() {
int sum, counter = 1;
while (counter < 1000) {
printf("Calculating...\n");
printf("%d numbers already verified.\n", counter);
if ( counter % 3 == 0 || counter % 5 == 0 ) {
sum += counter;
}
++counter;
}
printf("The sum of all multiples is: %d", sum);
return 0;
}
Java:
package problems;
//Prints the sum of all the multiples of 3 or five below 1000
public class Problem1 {
public static void main(String[] args) {
int sum = 0, counter = 1;
while (counter < 1000) {
System.out.format("Calculating...%n");
System.out.format("%d numbers already verified.%n",counter);
if( (counter % 3 == 0) || (counter % 5 == 0) ) {
sum += counter;
}
++counter;
}
System.out.format("The sum of all multiples is: %d", sum);
}
}
C outputs 2919928 as the total sum, while Java outputs 233168.
The problem in your code is that you are not initializing the variable sum.
The value of sum, when not initialized, is undefined. Therefore sum will take the value of what is currently in memory, which produces inaccuracies like this.
Intialize the variable sum to 0 and you should get the correct result.
In the C code you've written
int sum, counter = 1;
This means that the sum is not initialized with a value.
Unlike in Java the defult value for an int is not zero in C. Take a look at the question here for more details.
This value could be a garbage value and your code will add to that value instead of zero giving an invalid result.
To fix your code simply initialize sum when declaring the variable.
int sum = 0;
int counter = 1;

Sum of factorials

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.

Prime Number Finder has a mind of its own?

I am making a prime number finder, that would find the prime numbers for a given number that the user inputs. What I have now seems to either miss primes, or add non-primes to the ArrayList. My code seems logical to me, and I'm confused as to why this is happening. Can anyone tell me what I am doing wrong? Or maybe a simpler way to do this (I feel like I am over-complicating)? Some examples of errors would be: Enter 21, only 3 shows as a prime. Enter 11000, 25 and 55 show up (not prime obviously). Thanks in advance!
import java.util.*;
public class PrimeFactors {
public static void main(String args[]) {
long num;
Scanner in = new Scanner(System.in);
System.out.println("\n\n\nThis program finds the prime factors of a given number.\n");
System.out.print("Please enter the number: ");
num = in.nextLong();
System.out.println("\nThe prime factors are: " + primeFactor(num) + "\n");
}
public static ArrayList<Long> primeFactor(long n) {
long output = 0;
long guess = 2;
ArrayList<Long> primeFactors = new ArrayList<Long>();
while (guess <= n) {
long primes = 0;
long i = 2;
long x = 0;
long rt = 1;
long duplicate = 0;
output = n % guess;
// Finds the sqrt.
while (x <= n) {
x = rt * rt;
rt++;
}
// Finds odd factors.
if ((output == 0) && (guess % 2 != 0)) {
// This divides the odd factor by an incrementing number that is not 1 or the number itself.
while (i < rt) {
primes = primes + (guess % i);
// If the sum of the remainders to the division is not 0, then the number is prime.
// I used duplicate to make sure it didn't just go through once and count as prime.
if (primes != 0){
// There were duplicates, so I added them for the division later.
duplicate = duplicate + guess;
// This was used to wait for the while loop to finish, then find if the amount of times the guess went through was equal to its value - 1 and another 1 for the final number (primes are only divisible by one and itself).
if (i == (factors - 1)) {
if ((duplicate / guess) == (guess- 2)) {
primeFactors.add(guess);
}
}
}
i++;
}
}
guess++;
}
return primeFactors;
}
}
The math and logic you're doing here is very strange and I don't quite follow what's happening.
To that end, I would vote +1 for making the code simpler. This can be done with two simple methods. The first method will find factors for a number and run them through a prime checker. If they are a factor and pass the prime check, they get added to the array.
Bonus points: increase the speed of the algorithm by only searching through the bottom half of each of the factor checker and prime checker. Logic being that any value beyond half a number cannot be a factor of that number.
More bonus points for speed, increment by 2 skipping all multiples of 2, since they are automatically not prime. Good luck!
import java.util.ArrayList;
import java.util.Scanner;
/***************************************************
*
* #file: PrimeFactors.java
* #date: Mar 17, 2013
* #author: AaronW
*/
/**
*
* #author AaronW
*/
public class PrimeFactors {
public PrimeFactors() {
}
/**
*
* #param args
*/
public static void main(String[] args) {
long num;
Scanner in = new Scanner(System.in);
System.out.println("\n\n\nThis program finds the prime factors of a given number.\n");
System.out.print("Please enter the number: ");
num = in.nextInt();
System.out.println("\nThe factors are: " + findFactors((double)num) + "\n");
}
public static ArrayList<Integer> findFactors(Double num) {
ArrayList<Integer> factors = new ArrayList<Integer>();
for (int x = 1; x <= num; x++) {
System.out.println("Testing " + num + " % " + x + " = " + num % x);
// First, let's see if a number is factor of your target number
if (num % x == 0) {
System.out.println(x + " is a factor");
// Now that we know it's a factor, let's test to see if it's prime
if (isPrime(x)) {
// If it's prime, add it to the ArrayList
System.out.println("And " + x + " is prime.");
factors.add(x);
} else {
System.out.println("But " + x + " is not prime.");
}
} else {
System.out.println(x + " is not a factor");
}
}
return factors;
}
public static boolean isPrime(double num) {
// Let's start by assuming everything is prime and try to prove that false
// If we fall through the loop without proving it false, we have a prime
boolean prime = true;
for (int x = 2; x < num; x++) {
// if our target number can be divided by any number between 1 and itself, it is not prime
if (num % x == 0) {
prime = false;
}
}
return prime;
}
}
For a start, instead of
long x = 0;
long z = 1;
while (x <= n) {
x = z * z;
z++;
}
while (j < z) {
You can just do this
z = (int) Math.Sqrt(n)
while (j <= z) {
Then for each j I would check if it divides n with no remainder.
If it divides n with no remainder, divide n by j and add j to the prime factors. Then instead of incrementing j, try the same j again, for instance for 9 you do 3 twice for its factors.
Anything more complex than that is unnecessary - you will try each j until it can divide into n no more, and you will always try primes before composites formed of those primes, so you know off the bat you'll end up with only prime factors.
OK, there are a few problems with your code:
j, x, j & n, poorly named variables make for hard work debugging.
Where are your System.out.println() calls so you can see what is going on in your code?
The square root of n would be a more optimal point to stop looking for prime up to n.
Can I suggest you look at this: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes for a rapid way of finding primes.
One suggestion to make the code simpler. In you primeFactors method, first findout is it a factor, which I believe you are already doing, then call another method to determine if this is a prime. If that is prime add to the list.
I'll give you some pseudo-code for a simple to implement (not efficient) algorithm:
the value to factorize is N
keep going until N is equal to one
start at 2 and find lowest number X that divides N evenly
X is one factor
N/X is your new N to factor
Your variable names are inconsistent. factors is particularly bad, as it is only a guess of a single factor. Call it guess instead.
The arithmetic you do with factors, primes, and dup are also strange. Why are you adding to dup or primes? Try being your own computer, and executing your algorithm for the number 12; you'll see that you don't have a correct algorithm at all.
You've foreclosed the possibility of repeated factors by incrementing factors at the end.

Categories

Resources