Java Program to compute nCr throwing Arithmetic Exception "Divide by zero" - java

Following code tries to compute the nCr values for the various values of given n and here r varies from 0 to n.
The input is in the following format :-
Input Format
The first line contains the number of test cases T.
T lines follow each containing an integer n.
Constraints
1<=T<=200
1<=n< 1000
Output Format
For each n output the list of nC0 to nCn each separated by a single space in a new line. If the number is large, print only the last 9 digits. i.e. modulo 10^9
So Sample Input is of the follwing format :-
3
2
4
5
And the sample output is of the follwing format :-
1 2 1
1 4 6 4 1
1 5 10 10 5 1
Here is the code
import java.io.*;
import java.util.*;
import java.math.*;
public class Solution {
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int j = 0;
for(int i = 0; i < n; i++){
int a = scan.nextInt();
j = 0;
while(j <= a){
if( j == 0 || j == a){
System.out.print(1 + " ");
}
else if( j == 1 || j == (a - 1)){
System.out.print(a + " ");
}else{
BigInteger a1 = (Num(a,j));
BigInteger b1 = BigInteger.valueOf(fact(j));
BigInteger c1 = a1.divide(b1);
BigInteger x1 = BigInteger.valueOf(1000000000);
System.out.print( c1.mod(x1) +" ");
}
j++;
}
System.out.println();
}
}
public static BigInteger Num(int a, int j){
BigInteger prod = BigInteger.valueOf(1);
for(int k = 0; k < j; k++){
int z = a - k;
BigInteger b = BigInteger.valueOf(z);
prod = prod.multiply(b);
}
return prod;
}
public static long fact(long j){
long prod = 1;
for(long i = j; i > 0; i--){
prod *= i;
}
return prod;
}
}
Its clearing some test cases but its failing in many of them.
Saying Run Time Error, when I tested it on my input of 1 999 it threw Arithmetic Exception "Divide by zero".
Here is the exception log :-
Exception in thread "main" java.lang.ArithmeticException: BigInteger divide by zero
at java.math.MutableBigInteger.divideKnuth(MutableBigInteger.java:1179)
at java.math.BigInteger.divideKnuth(BigInteger.java:2049)
at java.math.BigInteger.divide(BigInteger.java:2030)
at Solution.main(Solution.java:25)
What needs to be done to fix this?

You must use BigInteger for the computation of factorials up to around 1000.
public static BigInteger fact(long j){
BigInteger prod = BigInteger.ONE;
for(long i = j; i > 0; i--){
BigInteger f = BigInteger.valueOf( i );
prod = prod.multiply( f );
}
return prod;
}

Related

Coding up to Factorial 23 in Java

I need to write up factorial up to 23! I can do factorial up to 20! but after that I am lost because the number gets too big. I cannot use BigInteger.
I have to store the 0s from the rightmost digit so example outputs:
10! = 3628800 --> fac=36288, num10 = 2
23! = 2585..976640000 --> fac= 2585..97664, num10 = 4
import java.util.Scanner;
public class Factorial10{
public static void main(String[] args){
long fac; // long: factorial is very large
long pre_fac; // to check overflow
int i, n;
int num10;
Scanner sc = new Scanner(System.in);
System.out.print("n? ");
n = sc.nextInt();
// Start from fac = 0! = 1
for(i= 1, fac= 1L; i<n; i++){
pre_fac = fac;
fac *= i;
// check if overflowed
if(pre_fac != fac /i){
System.out.println("Overflowed at " + i + "! = " + fac);
fac = pre_fac; // roll back to the previous, unoverflowed
break;
}
}
System.out.println((i-1) + "! = " + fac + "(fac = , num10 = )");
}
}
```
Most miss a crucial part of your question:
I have to store the 0s from the rightmost digit
10 has the factors 2 and 5, so you only need to store how often each number between 1 and 23 can be divided by 2 and 5.
For example, with 10:
i 1 2 3 4 5 6 7 8 9 10 SUM
div2 0 1 0 2 0 1 0 3 0 1 8
div5 0 0 0 0 1 0 0 0 0 1 2
As we can see, the minimum of both sums is 2, so 10! should end with 00.
Indeed, 10! is 3628800.
The math behind this is 10! = x * 2^8 * 5^2, for some x that can't be divided by 2 or 5.
An other observation is that the number of 5s increases much slower, so we can skip counting the 2s.
With this knowledge, we can calculate the number of ending 0s by checking how often each number divides 5:
private static int numZerosInFactorial(int n) {
int divBy5 = 0;
for (int i = 1; i <= n; i++) {
for (int j = i; (j % 5) == 0; j /= 5) {
divBy5++;
}
}
return divBy5;
}
(There are are a few small improvements you can do to the above method)
The other question now is: Do you really need the value of n!?
And if yes, with what precision? Is it fine to calculate n! with double now?
Thanks to a comment from Michael, I noticed that we can in fact calculate the factorial without the zeros and then use string concatenation to display the result.
When calculating the factorial without zeroes, we have to basically do the opposite of what we did in numZerosInFactorial, so instead of multiplying with a multiple of 5, we divide by 2:
private static long factorialWithoutZeroes(int n) {
long result = 1;
for (int i = 1; i <= n; i++) {
long div = 1;
int j;
for (j = i; (j % 5) == 0; j /= 5) {
div *= 2;
}
result = result / div * j;
}
return result;
}
The final result would be:
// We have already read n from stdin
long fac = factorialWithoutZeroes(n);
int num10 = numZerosInFactorial(n);
System.out.println(n + "! = " + (fac + "0".repeat(num10)) + " (fac = " + fac + " , num10 = " + num10 + ")");
Indeed, this approach works up to n == 23. And the output format is a good hint that this is the expected approach.
Have you try to use double instead of long. As documentation in Double.Max - it can hold up to 1.7976931348623157e+308
Just implement your own kind of big integer:
import java.util.Arrays;
class Main {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int[] factorial = factorial(n);
for (int i = factorial.length - 1; i >= 0; i--) {
System.out.print(factorial[i]);
}
}
static int[] factorial(int n) {
int[] factorial = { 1 };
for (int i = 1; i <= n; i++) {
factorial = multiply(factorial, i);
}
return factorial;
}
static int[] multiply(int[] multiplicand, int multiplicator) {
int carry = 0;
for (int j = 0; j < multiplicand.length; j++) {
multiplicand[j] = multiplicand[j] * multiplicator + carry;
carry = multiplicand[j] / 10;
multiplicand[j] %= 10;
}
while (carry > 0) {
multiplicand= Arrays.copyOf(multiplicand, multiplicand.length + 1);
multiplicand[multiplicand.length - 1] = carry % 10;
carry /= 10;
}
return multiplicand;
}
}
Try it online!
If you can't use BigInteger, then you could try implementing your own big number library:
How to handle very large numbers in Java without using java.math.BigInteger
You can use the class BigDecimal of java.lang.math
But that can take all your memory.
Is there any replacement of long double in java?

Two different outputs

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with and , the first 10 terms will be:
1,1,2,3,5,8,13,21,34,...
And here we should find the even numbers in Fibonacci series and add them to the sum
And the code :
import java.util.*;
public class Abhi {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
int[] n = new int[t];
int i,j;
long sum;
for(int a0 = 0; a0 < t; a0++){
n[a0] = in.nextInt();
}
//int an = n.length;
int[] nn = new int[1000];
nn[0]=1;
nn[1]=2;
for(i = 0 ; i<t;i++){
sum = 2;
for(j= 2;j<n[i];j++){
nn[j] = nn[j-2] + nn[j-1];
if(nn[j]%2==0 && nn[j]<n[i])
{
sum += nn[j];
//System.out.println(sum);
//the above line shows correct output
}
}
System.out.println(sum);//this is printing different output
}}}
Sample input :
1
100
Sample output :
44
Here problem in not with the outer System.out.println(sum); as you mentioned. It is because of int range.
Max value of int is 2 147 483 647 and in Fibonacci series 2 971 215 073 is in 47th position and as it exceeds the int range, it giving the results in unexpected manner.
In your code array nn holding -1323752223 instead of 2971215073 which is actually causing the issue.
To resolve this issue use BigInteger as below
BigInteger sum;
BigInteger[] nn = new BigInteger[1000];
nn[0] = new BigInteger("1");
nn[1] = new BigInteger("2");
for (i = 0; i < t; i++) {
sum = new BigInteger("2");
for (j = 2; j < n[i]; j++) {
nn[j] = nn[j - 2].add(nn[j - 1]);
if (nn[j].mod(new BigInteger("2")).equals(new BigInteger("0")) &&
nn[j].compareTo(new BigInteger(String.valueOf(n[i])))<0) {
sum = sum.add(nn[j]);
System.out.println(sum);
}
}
System.out.println(sum);
}
You can also achieve this by using below code:
import java.util.Scanner;
public class Fibo
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int No = sc.nextInt();
int fNo1 = 1;
int fNo2 = 1;
int fNo3 = fNo1 + fNo2;
int sumofEvenNo = 0;
int i;
while( fNo3 < No)
{
if(fNo3 % 2 == 0)
sumofEvenNo += fNo3;
fNo1 = fNo2;
fNo2 = fNo3;
fNo3 = fNo1 + fNo2;
}
System.out.println("Sum of all even nos = "+sumofEvenNo);
}
}
I suggest using naming convention, your code will be more clear and easy to debug. I'm using a static method to get the sum also.
Ask how many times the sum will be calculated.
Get the index and calculate the sum.
Print.
Class:
import java.util.*;
public class Abhi {
public static void main(String[] args) {
System.out.println ( "This program will calculate the even sum of given fibonacci series index ( index starts at 1) " );
System.out.println ( "Please enter how many times do you want to calculate the sum: " );
Scanner scan = new Scanner(System.in);
int iterationTimes = scan.nextInt() ;
for (; iterationTimes > 0; iterationTimes-- )
{
System.out.println ( "Please, enter the index on fibonacci: " );
System.out.println ( "Even sum: " + getEvenSum( scan.nextInt() ) );
}
}
private static long getEvenSum( int index)
{
if ( index <= 2 )
{
return 0;
}
long n1=1, n2=1, n3, sum = 0;
for(int i = 2; i < index; i++)
{
n3=n1+n2;
if ( n3 % 2 == 0)
{
sum += n3;
}
n1=n2;
n2=n3;
}
return sum;
}
}
I/O Example:
This program will calculate the even sum of given fibbonacci series index ( index starts at 1 )
Please enter how many times do you want to calculate the sum:
3
Please, enter the index on fibbonacci:
3
Even sum: 2
Please, enter the index on fibbonacci:
6
Even sum: 10
Please, enter the index on fibbonacci:
12
Even sum: 188
Note: Fibbonaci: 1, 1, 2, 3 ...

Whats wrong in this Binomial Theorem calculator?

After thinking about for 1 hour I am still not able to figure out whats the problem with my calculator. I have made 3 function which include main(), calculateBinomialTheorem() and factorial(). Yes, factorial() to calculate the coefficient.
public static void main(String[] args) {
Scanner a_input = new Scanner(System.in);
Scanner b_input = new Scanner(System.in);
Scanner n_input = new Scanner(System.in);
int a = 0;
int b = 0;
int n = 0;
System.out.println("Welcome to Binomial Theorem Solver:");
System.out.print("a: ");
a = a_input.nextInt();
System.out.print("b: ");
b = b_input.nextInt();
System.out.print("n: ");
n = n_input.nextInt();
System.out.print(calculateBinomialTheorem(a, b, n));
a_input.close();
b_input.close();
n_input.close();
}
private static int calculateBinomialTheorem(int a, int b, int n) {
int result = 0;
int coefficient = 0;
ArrayList<Integer> products = new ArrayList<Integer>();
for(int i = 1; i <= n; i++) {
int product = 0;
coefficient = factorial(n) / (factorial(i) * factorial(n - i));
product = (int) (coefficient*Math.pow(a, n - i)*Math.pow(b, i));
products.add(product);
}
for(int c : products) {
result += c;
}
return result;
}
private static int factorial(int num) {
int factorial = 1;
if(num > 0) {
for ( int c = 1 ; c <= num ; c++ )
factorial = factorial*c;
} else {
return 0;
}
return factorial;
}
I tried to run it with the values of 3, 3, 3 that should give me the answer of 216 but its not giving! Why? Every time I run it with those values this is the error that I get:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at binomial_thorem_solver.Main.calculateBinomialTheorem(Main.java:46)
at binomial_thorem_solver.Main.main(Main.java:29)
I know that I am dividing the number by 0 but I am not getting how to resolve that issue.
Please help.
UPDATE: Thanks for the answers. You all figured out what the problem was but then there was another problem aswell that the loop was iterating one less time because i waas initially set to 1. I set that to 0 and it worked!
The problem is in your factorial method.. for 0 your factorial will return 0..
and you are dividing the value with the result of factorial (i.e. 0).. the factorial of 0 is 1. so your code should be
private static int factorial(int num) {
int factorial = 1;
if(num > 0) {
for ( int c = 1 ; c <= num ; c++ )
factorial = factorial*c;
} else {
return 1;
}
return factorial;
}
In the first iteration, i = 1, you have:
coefficient = factorial(n) / (factorial(i) * factorial(n - i));
What is factorial(1)? It's 1 according to your code.
What is dactorial(0)? It's 0 according to your code (if(num > 0) is false, so you go to else - there you return 0).
So, as the exception is telling you, you are trying to divide by zero.
How to fix this?
0! is defined to be 1. So you should check this special case and return 1 if the number is 0.
0! = 1 by convention. Not 0. This might cause problem to you.
Moreover, for loop should go from 0 to n, not from 1 to n as there are n+1 terms.
You are missing C(n,0)*a^0*b^n part as your iteration is not going from 0 to n.
So, your loop should be
for(int i = 0; i <= n; i++) {
int product = 0;
coefficient = factorial(n) / (factorial(i) * factorial(n - i));
product = (int) (coefficient*Math.pow(a, n - i)*Math.pow(b, i));
products.add(product);
}
In your case, since C(3,0)*3^0*3^3 that is 27 is missing from the final product. That is why you are getting 216 - 27 = 189.
You need to return 1 from the factorial functiom if num is zero.
factorial 0 equals 1.
if(num > 0) {
for ( int c = 1 ; c <= num ; c++ )
factorial = factorial*c;
} else {
return 1;
}

Interesting Program behaviour for Project Euler p21

I have got a solution for problem 21 in python and it gives the right answer. I tried out someone else's java code and I get the same answer for a value of 10000 and 100000 but when 1000000 is tried, the solution returned by my code differs from two other solutions returned by java code even though all three solutions returned are same for tested values of 10000 and 1000000 and 50000. Anyone got any ideas?
My Python code
def amicable_pairs(n):
"""returns sum of all amicable pairs under n. See project euler for
definition of an amicable pair"""
div_sum = [0]*n
amicable_pairs_set = [0]*n
for i in range(1, n):
for j in range(i*2, n, i):
div_sum[j] += i
#for i in range(1, n):
# div_sum[i] = sum([j + i/j for j in range(2, int(math.sqrt(i)) + 1) if i % j == 0 and i != i/j])
# div_sum[i] = div_sum[i] + 1
#print div_sum
for j in range(n):
if div_sum[j] < n and div_sum[div_sum[j]] == j and div_sum[j] != j:
amicable_pairs_set[j] = j
amicable_pairs_set[div_sum[j]] = div_sum[j]
return sum(amicable_pairs_set)
Java code 1:
public class AmicableNumbers {
public static void main(String[] args) {
long strTime = System.currentTimeMillis();
int sum_ami = 0;
for (int j = 1; j < 1000000; j++) {
int ad = sum_devisors(j);
if (((sum_devisors(ad)) == j) && (j != ad)) {
sum_ami += j;
}
}
System.out.println(sum_ami);
long endTime = System.currentTimeMillis();
System.out.println("time is " + (endTime - strTime) + " ms");
}
public static int sum_devisors(int number) {
if ((number == 1) || (number == 2)) {
return 1;
}
int sum = 0;
int k = (int) Math.sqrt(number);
for (int i = 2; i < k; i++) {
if (number % i == 0) {
sum += i;
sum += (number / i);
}
}
if (k * k == number) {
sum += k;
}
return (sum + 1);// every number divided by 1
}
}
Java code 2:
import java.util.Scanner;
public class AmicableNumbers {
/**
* #author Pavan Koppolu
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//scan the input
System.out.println("Enter a number, to find out sum of amicable numbers: ");
Scanner scan=new Scanner(System.in);
int input=scan.nextInt();
long before=System.currentTimeMillis();
// getting the result
long result=sumOfAllAmicableNumbersUptoGivenNumber(input);
long after=System.currentTimeMillis();
// prints the result on the console
System.out.println("Sum of all amicable numbers below "+input+" : "+result+" Elasped Time : "+(after-before)+" ms");
}
/*
* calculate the sum of the amicable numbers upto the given number
*/
private static long sumOfAllAmicableNumbersUptoGivenNumber(int input)
{
long sum=0,factorsSum=0,sumOfFactors=0;
for(long j=2;j<input;j++)
{
factorsSum=getFactorsSum(j);
if(j!=factorsSum)
{
sumOfFactors=getFactorsSum(factorsSum);
if(j==sumOfFactors)
sum+=j;
}
else
continue;
}
return sum;
}
/*
* find out the sum of the factors
*/
private static long getFactorsSum(long j)
{
long sum=1;
for(int k=2;k<=Math.sqrt(j);k++)
{
if(j%k==0)
sum+=k+j/k;
}
return sum;
}
}
In fact the solutions returned by all three above differ from each other for an input of 1000000
The point is that there are amicable pairs where one partner is less than 1 million and the other is larger than 1 million, namely
(947835,1125765), (998104,1043096)
The Python code doesn't count them,
for j in range(n):
if div_sum[j] < n and div_sum[div_sum[j]] == j and div_sum[j] != j:
but the Java code counts the smaller members of these pairs. That explains the output of the second Java code, since
25275024 + 947835 + 998104 == 27220963
The output of the first Java code is smaller because it omits the amicable pair
(356408, 399592)
The reason is that
356408 = 596*598
but in the code there is
int k = (int) Math.sqrt(number);
for (int i = 2; i < k; i++) {
thus the divisor sum is miscalculated for all numbers divisible by floor(sqrt(n)) that are not squares (Note that the second Java code miscalculates the divisor sum for all squares).

CodeChef Array Transform Program

Here's the Problem Statement :
Given n numbers, you can perform the following operation any number of
times : Choose any subset of the
numbers, none of which are 0.
Decrement the numbers in the subset by
1, and increment the numbers not in
the subset by K. Is it possible to
perform operations such that all
numbers except one of them become 0 ?
Input : The first line contains the
number of test cases T. 2*T lines
follow, 2 for each case. The first
line of a test case contains the
numbers n and K. The next line
contains n numbers, a_1...a_n. Output
: Output T lines, one corresponding to
each test case. For a test case,
output "YES" if there is a sequence of
operations as described, and "NO"
otherwise.
Sample Input :
3
2 1
10 10
3 2
1 2 2
3 2
1 2 3
Sample Output :
YES
YES
NO
Constraints :
1 <= T <= 1000
2 <= n <= 100
1 <= K <= 10
0 <= a_i <= 1000
& here's my code :
import java.util.*;
public class ArrayTransform {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int no_of_tests = sc.nextInt();
int size;
int a[] = new int[100];
boolean yes;
int j;
int k;
for (int i = 0; i < no_of_tests; i++) {
size = sc.nextInt();
k = sc.nextInt();
for (j = 0; j < size; j++) {
a[j] = sc.nextInt();
}
yes = is_possible(a, size, k + 1);
if (yes)
System.out.println("YES\n");
else
System.out.println("NO\n");
}
}
static boolean is_possible(int a[], int size, int k_1) {
int count = 0;
int m[] = { -1, -1 };
int mod;
for (int i = 0; i < size; i++) {
mod = a[i] % k_1;
if (m[0] != mod && m[1] != mod) {
if (m[0] == -1)
m[0] = mod;
else if (m[1] == -1)
m[1] = mod;
else
return false;
}
}
return true;
}
}
if (m[0] != mod && m[1] != mod)
Here instead of && there should be ||. Only one of the m's need to match the mod.

Categories

Resources