Competitive Programing: Factorial Time limit exceeded - java

I am working on a very simple spoj problem in which we have to take input N calculate its factorial then find out number of trailing zeros and display it some thing like
Sample Input:
6
3
60 // fact of 60 has 14 trailing zeros
100
1024
23456
8735373
Sample Output:
0
14
24
253
5861
2183837
so i have written a code which is working fine on my machine but when i am submitting it is giving me time limit error. i don't know how to make this code fast. So i want suggestions from you guys.
public class Factorial {
public static void main(String[] args) throws IOException {
try {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(bf.readLine());
for (int i = 0; i < t; i++) {
Long num = Long.parseLong(bf.readLine());
BigInteger bd = BigInteger.valueOf(num);
System.out.println(countTrailinZeros(factorial(bd.toString())));
}
} catch (IllegalStateException e) {
return;
}
}
public static BigInteger factorial(String n) {
BigInteger x = BigInteger.valueOf(1);
for (long i = 1; i <= Integer.parseInt(n); i++) {
x = x.multiply(BigInteger.valueOf(i));
}
return x;
}
public static int countTrailinZeros(BigInteger bd) {
String s = bd.toString();
int glen = s.length();
s = s.replaceAll("[0.]*$", "");
int llen = s.length();
return glen - llen;
}
}
I have googled about some possible solutions and found out that lookup table may work i don't have much idea about this. I'd be very thankful if some can explain me about lookup table.
edit: Could it be java is too slow to solve this problem in given time? or in general it is not favorable to use java for competitive programing?

you dont need to calculate factorial to get number of trailing zeroes.
Solution :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int lines = Integer.parseInt(br.readLine());
int sum, N, p;
for (int i = 0; i < lines; i++) {
N = Integer.parseInt(br.readLine());
sum = 0;
p = 5;
while (N / p != 0) {
sum = sum + N / p;
p = p * 5;
}
System.out.println(sum);
}
}
}
Logic is :
The highest power of a prime number p in N! is given by
floor(N/p) + floor(N/p*p) + floor(N/p*p*p) ... so on till [floor(N/p^n) = 0]
so since number of ending zeroes is required , ans = min(max power of 2 in N!, max power of 5 in N!)
because zeroes appears on multiplication by ten and ten can be decomposed to 10 = (2 * 5).
It is fine to assume that max power of 5 in N! is always less than max power of 2 in N!.
as multiples of 2 occur more frequently than multiples of 5.
So problem reduces to finding max power of 5 in N! and hence the solution.
Example :
N = 5
max power of 5 in 5! = floor(5/5) + floor(5/25) => 1 + 0 => ans = 1
N = 100
max power of 5 in 100! = floor(100/5) + floor(100/25) + floor(100/125) => 20 + 4 + 0 => ans = 24

I have solved the same problem in spoj platform, you just have to divide the value by 5 until the value becomes less than 5. print all the result of the division and that's your output.

To solve this problem, consider prime factorization of N factorial:
N! = 2^a1 * 3^a2 * 5^a3 * .... where a1, a2, a3, ... >= 0
Since N! = N*(N-1)(N-2)..., multiples of 2 are more frequent than 5.
So, a1 >= a3 in this expansion.
Number of trailing zeros = how many times you can divide N! by 10.
Which implies, ans = min(a1, a3) based on the prime factorization given above.
Since we already proved a1 >= a3, hence ans = a3, i.e power of 5 in the prime factorization of N!.
There will be floor(N/5) numbers that will contribute to power of 5 atleast once.
There will be floor(N/25) numbers that will contribute to power of 5 atleast twice.
There will be floor(N/125) numbers that will contribute atleast thrice
and so on.
The total power of 5 = floor(N/5) + floor(N/25) + floor(N/125) + ...
Implementation of this formula in code is left as an exercise.

Related

Down to Zero II

This is the question:
You are given Q queries. Each query consists of a single number N . You can perform any of the operations on in each move:
If we take 2 integers a and b where N=a*b (a ,b cannot be equal to 1), then we can change N=max(a,b)
Decrease the value of N by 1 .
Determine the minimum number of moves required to reduce the value of to .
Input Format
The first line contains the integer Q.
The next Q lines each contain an integer,N .
Output Format
Output Q lines. Each line containing the minimum number of moves required > to reduce the value of N to 0.
I have written the following code. This code is giving some wrong answers and also giving time limit exceed error . Can you tell what are the the mistakes present in my code ? where or what I am doing wrong here?
My code:
public static int downToZero(int n) {
// Write your code here
int count1=0;
int prev_i=0;
int prev_j=0;
int next1=0;
int next2=Integer.MAX_VALUE;
if (n==0){
return 0;
}
while(n!=0){
if(n==1){
count1++;
break;
}
next1=n-1;
outerloop:
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
if (i*j==n){
if (prev_i ==j && prev_j==i){
break outerloop;
}
if (i !=j){
prev_i=i;
prev_j=j;
}
int max=Math.max(i,j);
if (max<next2){
next2=max;
}
}
}
}
n=Math.min(next1,next2);
count1++;
}
return count1;
}
This is part is coded for us:
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
int q = Integer.parseInt(bufferedReader.readLine().trim());
for (int qItr = 0; qItr < q; qItr++) {
int n = Integer.parseInt(bufferedReader.readLine().trim());
int result = Result.downToZero(n);
bufferedWriter.write(String.valueOf(result));
bufferedWriter.newLine();
}
bufferedReader.close();
bufferedWriter.close();
}
}
Ex: it is not working for number 7176 ....
To explore all solution tree and find globally optimal solution, we must choose the best result both from all possible divisor pairs and from solution(n-1)
My weird translation to Java (ideone) uses bottom-up dynamic programming to make execution faster.
We calculate solutions for values i from 1 to n, they are written into table[i].
At first we set result into 1 + best result for previous value (table[i-1]).
Then we factor N into all pairs of divisors and check whether using already calculated result for larger divisor table[d] gives better result.
Finally we write result into the table.
Note that we can calculate table once and use it for all Q queries.
class Ideone
{
public static int makezeroDP(int n){
int[] table = new int[n+1];
table[1] = 1; table[2] = 2; table[3] = 3;
int res;
for (int i = 4; i <= n; i++) {
res = 1 + table[i-1];
int a = 2;
while (a * a <= i) {
if (i % a == 0)
res = Math.min(res, 1 + table[i / a]);
a += 1;
}
table[i] = res;
}
return table[n];
}
public static void main (String[] args) throws java.lang.Exception
{
int n = 145;//999999;
System.out.println(makezeroDP(n));
}
}
Old part
Simple implementation (sorry, in Python) gives answer 7 for 7176
def makezero(n):
if n <= 3:
return n
result = 1 + makezero(n - 1)
t = 2
while t * t <= n:
if n % t == 0:
result = min(result, 1 + makezero(n // t))
t += 1
return result
In Python it's needed to set recursion limit or change algorithm. Now use memoization, as I wrote in comments).
t = [-i for i in range(1000001)]
def makezeroMemo(n):
if t[n] > 0:
return t[n]
if t[n-1] < 0:
res = 1 + makezeroMemo(n-1)
else:
res = 1 + t[n-1]
a = 2
while a * a <= n:
if n % a == 0:
res = min(res, 1 + makezeroMemo(n // a))
a += 1
t[n] = res
return res
Bottom-up table dynamic programming. No recursion.
def makezeroDP(n):
table = [0,1,2,3] + [0]*(n-3)
for i in range(4, n+1):
res = 1 + table[i-1]
a = 2
while a * a <= i:
if i % a == 0:
res = min(res, 1 + table[i // a])
a += 1
table[i] = res
return table[n]
We can construct the directed acyclic graph quickly with a sieve and
then compute shortest paths. No trial division needed.
Time and space usage is Θ(N log N).
n_max = 1000000
successors = [[n - 1] for n in range(n_max + 1)]
for a in range(2, n_max + 1):
for b in range(a, n_max // a + 1):
successors[a * b].append(b)
table = [0]
for n in range(1, n_max + 1):
table.append(min(table[s] for s in successors[n]) + 1)
print(table[7176])
Results:
7
EDIT:
The algorithm uses Greedy approach and doesn't return optimal results, it just simplifies OP's approach. For 7176 given as example, below algorithm returns 10, I can see a shorter chain of 7176 -> 104 -> 52 -> 13 -> 12 -> 4 -> 2 -> 1 -> 0 with 8 steps, and expected answer is 7.
Let's review your problem in simple terms.
If we take 2 integers a and b where N=a*b (a ,b cannot be equal to 1), then we can change N=max(a,b)
and
Determine the minimum number of moves required to reduce the value of to .
You're looking for 2 factors of N, a and b and, if you want the minimum number of moves, this means that your maximum at each step should be minimum. We know for a fact that this minimum is reached when factors are closest to N. Let me give you an example:
36 = 1 * 36 = 2 * 18 = 3 * 12 = 4 * 9 = 6 * 6
We know that sqrt(36) = 6 and you can see that the minimum of 2 factors you can get at this step is max(6, 6) = 6. Sure, 36 is 6 squared, let me take a number without special properties, 96, with its square root rounded down to nearest integer 9.
96 = 2 * 48 = 3 * 32 = 4 * 24 = 6 * 16 = 8 * 12
You can see that your minimum value for max(a, b) is max(8, 12) = 12, which is, again, attained when factors are closest to square root.
Now let's look at the code:
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
if (i*j==n){
You can do this in one loop, knowing that n / i returns an integer, therefore you need to check if i * (n / i) == n. With the previous observation, we need to start at the square root, and go down, until we get to 1. If we got i and n / i as factors, we know that this pair is also the minimum you can get at this step. If no factors are found and you reach 1, which obviously is a factor of n, you have a prime number and you need to use the second instruction:
Decrease the value of N by 1 .
Note that if you go from sqrt(n) down to 1, looking for factors, if you find one, max(i, n / i) will be n / i.
Additionally, if n = 1, you take 1 step. If n = 2, you take 2 steps (2 -> 1). If n = 3, you take 3 steps (3 -> 2 -> 1). Therefore if n is 1, 2 or 3, you take n steps to go to 0. OK, less talking, more coding:
static int downToZero(int n) {
if (n == 1 || n == 2 || n == 3) return n;
int sqrt = (int) Math.sqrt(n);
for (int i = sqrt; i > 1; i--) {
if (n / i * i == n) {
return 1 + downToZero(n / i);
}
}
return 1 + downToZero(n - 1);
}
Notice that I'm stopping when i equals 2, I know that if I reach 1, it's a prime number and I need to go a step forward and look at n - 1.
However, I have tried to see the steps your algorithm and mine takes, so I've added a print statement each time n changes, and we both have the same succession: 7176, 92, 23, 22, 11, 10, 5, 4, 2, 1, which returns 10. Isn't that correct?
So, I found a solution which is working for all the test cases -
static final int LIMIT = 1_000_000;
static int[] solutions = buildSolutions();
public static int downToZero(int n) {
// Write your code here
return solutions[n];
}
static int[] buildSolutions() {
int[] solutions = new int[LIMIT + 1];
for (int i = 1; i < solutions.length; i++) {
solutions[i] = solutions[i - 1] + 1;
for (int j = 2; j * j <= i; j++) {
if (i % j == 0) {
solutions[i] = Math.min(solutions[i], solutions[i / j] + 1);
}
}
}
return solutions;
}
}

Terminated due to timeout error [duplicate]

I am working on a program that takes an integer and finds the number of combinations of consecutive sums that the integer has:
The number 13 can be expressed as a sum of consecutive positive
integers 6 + 7. Fourteen can be expressed as 2 + 3 + 4 + 5, also a sum
of consecutive positive integers. Some numbers can be expressed as a
sum of consecutive positive integers in more than one way. For
example, 25 is 12 + 13 and is also 3 + 4 + 5 + 6 + 7.
I researched and read that it's the number of odd factors minus one. So I wrote a program that finds the number of odd factors and my answer is still wrong in certain cases. Any insight?
Code seems to work fine but there is a crash due to Timeout which is probably due to optimization error.
The constraints for possible input size is
1 to 10^(12)
The code below is copied from alfasin's answer below:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
static long consecutive(long num) {
while (num % 2 == 0) num /= 2;
return consecutiveHelper(num);
}
public static long consecutiveHelper(long num) {
return LongStream.rangeClosed(3, (num / 2)).parallel().filter(x -> x % 2 != 0).map(fn -> (num % fn == 0) ? 1 : 0).sum();
}
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
final String fileName = System.getenv("OUTPUT_PATH");
BufferedWriter bw = null;
if (fileName != null) {
bw = new BufferedWriter(new FileWriter(fileName));
}
else {
bw = new BufferedWriter(new OutputStreamWriter(System.out));
}
int res;
long num;
num = Long.parseLong(in.nextLine().trim());
res = consecutive(num);
bw.write(String.valueOf(res));
bw.newLine();
bw.close();
}
}
This is what i currently have
As the post i answered to was duplicate, I copied my answer here as well.Let's try to find a pseudo-optimized method to resolve your problem :
What you need to do is to decompose your number in prime factors.
For example, if you take 1200 :
1200 = 2*2*2*2*3*5*5 = 1 * 2^4 * 3^1 * 5^2
You can then analyze how you could get odd factors with those prime factors. A quick analyze will tell you that :
odd * odd = odd
odd * even = even
even * even = even
With that in mind, let's find all the factors we get with odd * odd :
1 * 1 = 1
3 * 1 = 3
5 * 1 = 5
5 * 3 = 15
5 * 5 = 25
5 * 5 * 3 = 75
A quick way to find these combinations without writing them all is the "plus 1 method" : add 1 to the number of occurences of each prime odd factor, and multiply them together :
We found that 1200 = 1 * 2^4 * 3^1 * 5^2, so we can do :
("number of 3" + 1) ("number of 5" + 1) = (1 + 1) ( 2 + 1) = 6
There are 6 odd factors for the number 1200, and as you stated, remove 1 from that number to get the number of combinations of consecutive sums that 1200 has :
6 - 1 = 5 <-- woohoo ! finally got the result !
Now, let's look at the code. What we want to have is a Map, the keys being the prime factors and the values being the number of their occurences :
/*
If number is odd,
find the number in the keys and add 1 to its value.
If the number is not in the keys, add it with value = 1.
*/
public static void addValue(Map<Integer, Integer> factors, int i) {
if(i % 2 != 0) {
int count = factors.containsKey(i) ? factors.get(i) : 0;
factors.put(i, ++count);
}
}
/*
Classic algorithm to find prime numbers
*/
public static Map<Integer, Integer> oddPrimeFactors(int number) {
int n = number;
Map<Integer, Integer> factors = new HashMap<>();
for (int i = 2; i <= n / i; i++) {
while (n % i == 0) {
addValue(factors, i);
n /= i;
}
}
if(n > 1) addValue(factors, n);
return factors;
}
With that, let's try to print what the map contains for number 1200 :
public static void main(String[] args) {
int n = 1200;
System.out.println(oddPrimeFactors(n));
}
$n : {3=1, 5=2}
Good ! Now let's finish the program with the method we developed before :
public static int combinations = 1;
public static void main(String[] args) {
int n = 1200;
oddPrimeFactors(n).forEach((key, value) -> combinations *= (value + 1));
combinations--;
System.out.println(combinations);
}
$combinations = 5
Finished ! feel free to ask if you did not understand something !
Note : I tried my program with the max value Integer can handle and it took less than one second for my program to proceed, which seems pretty fast to me. It could probably be faster though, it's up to you to find the most optimized version of this code !
Here are the optimizations that we discussed in the comments section, see comments as markers:
static int consecutive(long num) {
while (num % 2 == 0) num /= 2; // 1st opt.
return consecutiveHelper(num)-1;
}
public static int consecutiveHelper(long num) {
long factorNumber = 1;
int count = 0;
while(factorNumber <= num / 2) { // 2nd opt.
if(num % factorNumber == 0) {
count++;
}
factorNumber += 2; // 3rd opt.
}
if (num % 2 != 0) {
count++;
}
return count;
}
UPDATE
I managed to reduce ~50% runtime for big-numbers (10^12) by using Java 8 Stream interface and running in parallel:
static long consecutive(long num) {
while (num % 2 == 0) num /= 2;
return consecutiveHelper(num);
}
public static long consecutiveHelper(long num) {
return LongStream
.rangeClosed(3, (num / 2))
.parallel()
.filter(x -> x % 2 != 0)
.map(fn -> (num % fn == 0) ? 1 : 0)
.sum();
}
That said, parallel will be more expensive when you're dealing with smaller numbers. If you want your answer to be optimal you should use both methods: for smaller numbers use the first and for large numbers use the latter.

Do-while loop factorial. ( factorial *= x will eventually give a negative number) [duplicate]

I am currently taking pre-calculus and thought that I would make a quick program that would give me the results of factorial 10. While testing it I noticed that I was getting incorrect results after the 5th iteration. However, the first 4 iterations are correct.
public class Factorial
{
public static void main(String[] args)
{
int x = 1;
int factorial;
for(int n = 10; n!=1; n--)
{
factorial = n*(n-1);
x = x * factorial;
System.out.printf("%d ", x);
}
}//end of class main
}//end of class factorial
That is an Integer Overflow issue. Use long or unsigned long instead of int. (And as #Dunes suggested, your best bet is really BigInteger when working with very large numbers, because it will never overflow, theoretically)
The basic idea is that signed int stores numbers between -2,147,483,648 to 2,147,483,647, which are stored as binary bits (all information in a computer are stored as 1's and 0's)
Positive numbers are stored with 0 in the most significant bit, and negative numbers are stored with 1 in the most significant bit. If your positive number gets too big in binary representation, digits will carry over to the signed bit and turn your positive number into the binary representation of a negative one.
Then when the factorial gets bigger than even what an unsigned int can store, it will "wrap around" and lose the carry-over from its most significant (signed) bit - that's why you are seeing the pattern of sometimes alternating positive and negative values in your output.
You're surpassing the capacity of the int type (2,147,483,647), so your result is wrapping back around to the minimum int value. Try using long instead.
Having said the that, the method you are currently employing will not result in the correct answer: actually, you are currently computing 10! ^ 2.
Why complicate things? You could easily do something like this:
long x = 1L;
for(int n = 1; n < 10; n++)
{
x *= n;
System.out.println(x);
}
1
2
6
24
120
720
5040
40320
362880
which shows successive factorials until 10! is reached.
Also, as others have mentioned, if you need values bigger than what long can support you should use BigInteger, which supports arbitrary precision.
Your formula for the factorial is incorrect. What you will have is this:
Step 1 : n*(n-1) = 10 * 9 = 90 => x = 1*90 = 90
Step 2 : n*(n-1) = 9 * 8 = 72 => x = 90*72 = 6480 or, it should be : 10 * 9 * 8 => 720
But the wrong results are coming from the fact that you reached the maximum value for the type int as pointed out by others
Your code should be
public class Factorial
{
public static void main(String[] args)
{
double factorial = 1;
for(int n = factorial; n>=1; n--)
{
factorial = factorial * n;
System.out.printf("%d ", factorial );
}
}
}
In addition to what the other answers mention about the overflow, your factorial algorithm is also incorrect. 10! should calculate 10*9*8*7*6*5*4*3*2*1, you are doing (10*9)*(9*8)*(8*7)*(7*6)*...
Try changing your loop to the following:
int x = 1;
for(int n = 10; n > 1 ; n--)
{
x = x * n;
System.out.printf("%d ", x);
}
You will eventually overflow if you try to calculate the factorial of higher numbers, but int is plenty large enough to calculate the factorial of 10.

Algorithm to solve an equation

I have this problem for the course "Algorithm and data structures"
You have a equation x^2+s(x)+200·x=N, where x and N are natural numbers and S(x) is the sum of digits of number x.
On the input we have N and A, B such that A≤B and A, B≤1,000,000,000. You need to check if there is a natural number x in the interval [A, B] that solves the equation. If found you need to return that number, otherwise return -1.
Example Input:
1456
10 80
Output
-1
I managed to solve this problem by using some math and a bit modified version of brute force algorithm. But are there any more effective(algorithm based) ways to solve this problem?
This is my code:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Range {
static int proveri(long N, long A, long B) {
long res = 0;
long start = (long)((-200 + Math.sqrt(4*N + 4))/2);
//System.out.println(start);
for (long i = Math.max(A, start); i <= B; i++) {
res = i * i + S(i) + 200 * i;
if(res == N)
return (int)i;
if(res > N)
return -1;
}
return -1;
}
static int S(long x) {
int sum = 0;
while(x > 0) {
sum += x % 10;
x /= 10;
}
return sum;
}
public static void main(String[] args) throws Exception {
int i,j,k;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long N = Long.parseLong(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
long A = Long.parseLong(st.nextToken());
long B = Long.parseLong(st.nextToken());
int res = proveri(N, A, B);
System.out.println(res);
br.close();
}
}
Here's a way where you can cut down on the amount of numbers you have to search.
Consider the equation anxn +
an-1xn-1 + ... + a1x + a0 = 0.
The rational root theorem states that if x = p/q is a solution,
then p divides a0 and q divides an
In your case, an is 1 and a0 is equal to S(x)-N. Thus, we know that any solution must divide S(x)-N.
This is where ben75's tip comes in. Since S(x) can't be bigger than 81, we can loop through all of the possible values of S(x), and solve separately. Something like this:
for each possible value of S(x)
loop through every factor x of S(x) - N
check if it is between A and B, if its digits sum to S(x)
and if it is a solution to x*x + 200x + S(x) = N.
if it is, return it.
return -1
There's also a pretty slick way for you to loop through all of the factors of a number, but I'll let you work that one out for yourself since this is for a course. My hint there is to look at the prime factorization of a number.
For the equation x^2+s(x)+200·x=N, consider
x^2 + 200·x + (N - s(x)) = 0
For a solution to a*x^2 + b*x + c = 0 equation with integer solutions, we need to have:
b^2 - 4*a*c >= 0 and must be a perfect square
Hence 200^2 - 4 * (N - s(x)) >=0 and a square or
10000 >= (N - s(x)) and (10,000 - (N - s(x)) must be a square. The square value is therefore less than 10,000 and hence there can be at most 100 values you need to check. With proper values of N it can be much lesser.
Also note that since N < 10,000, s(x) can be at most 36. These should cut down the range quite a bit.

Factorial loop results are incorrect after the 5th iteration

I am currently taking pre-calculus and thought that I would make a quick program that would give me the results of factorial 10. While testing it I noticed that I was getting incorrect results after the 5th iteration. However, the first 4 iterations are correct.
public class Factorial
{
public static void main(String[] args)
{
int x = 1;
int factorial;
for(int n = 10; n!=1; n--)
{
factorial = n*(n-1);
x = x * factorial;
System.out.printf("%d ", x);
}
}//end of class main
}//end of class factorial
That is an Integer Overflow issue. Use long or unsigned long instead of int. (And as #Dunes suggested, your best bet is really BigInteger when working with very large numbers, because it will never overflow, theoretically)
The basic idea is that signed int stores numbers between -2,147,483,648 to 2,147,483,647, which are stored as binary bits (all information in a computer are stored as 1's and 0's)
Positive numbers are stored with 0 in the most significant bit, and negative numbers are stored with 1 in the most significant bit. If your positive number gets too big in binary representation, digits will carry over to the signed bit and turn your positive number into the binary representation of a negative one.
Then when the factorial gets bigger than even what an unsigned int can store, it will "wrap around" and lose the carry-over from its most significant (signed) bit - that's why you are seeing the pattern of sometimes alternating positive and negative values in your output.
You're surpassing the capacity of the int type (2,147,483,647), so your result is wrapping back around to the minimum int value. Try using long instead.
Having said the that, the method you are currently employing will not result in the correct answer: actually, you are currently computing 10! ^ 2.
Why complicate things? You could easily do something like this:
long x = 1L;
for(int n = 1; n < 10; n++)
{
x *= n;
System.out.println(x);
}
1
2
6
24
120
720
5040
40320
362880
which shows successive factorials until 10! is reached.
Also, as others have mentioned, if you need values bigger than what long can support you should use BigInteger, which supports arbitrary precision.
Your formula for the factorial is incorrect. What you will have is this:
Step 1 : n*(n-1) = 10 * 9 = 90 => x = 1*90 = 90
Step 2 : n*(n-1) = 9 * 8 = 72 => x = 90*72 = 6480 or, it should be : 10 * 9 * 8 => 720
But the wrong results are coming from the fact that you reached the maximum value for the type int as pointed out by others
Your code should be
public class Factorial
{
public static void main(String[] args)
{
double factorial = 1;
for(int n = factorial; n>=1; n--)
{
factorial = factorial * n;
System.out.printf("%d ", factorial );
}
}
}
In addition to what the other answers mention about the overflow, your factorial algorithm is also incorrect. 10! should calculate 10*9*8*7*6*5*4*3*2*1, you are doing (10*9)*(9*8)*(8*7)*(7*6)*...
Try changing your loop to the following:
int x = 1;
for(int n = 10; n > 1 ; n--)
{
x = x * n;
System.out.printf("%d ", x);
}
You will eventually overflow if you try to calculate the factorial of higher numbers, but int is plenty large enough to calculate the factorial of 10.

Categories