So consider the following program-segment! I've tried to use the basic recursion function to determine the factorial of a number, but now using the BigInteger class.
public static BigInteger fact(int a)
{
BigInteger factorial = BigInteger.ONE;
BigInteger factz = BigInteger.ONE;
if(a == 1)
{
return factorial;
}
else
{
return factz.multiply(fact(a-1));
}
}
So when I try implementing this in a program, it returns the output as 1. Is it because BigInteger objects are immutable? Or am I missing something here?
There's an error in the code, you should put
BigInteger factz = BigInteger.valueOf(a);
instead of BigInteger factz = BigInteger.ONE;
The pseudocode of calculate factorial recursively looks as:
function factorial(n) {
if (n == 0)
return 1;
else
return n * factorial(n - 1);
}
Implementing it with BigInteger will be:
public static BigInteger factorial(BigInteger n) {
if (n.equals(BigInteger.ZERO))
return BigInteger.ONE;
else
return n.multiply(factorial(n.subtract(BigInteger.ONE)));
}
public static void main(String[] args) {
System.out.println(factorial(new BigInteger("100")));
}
An output will be:
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Note: recursion takes too much memory if n is large. In this case it's better to use some iterative algorithm to calculate factorial.
I don't get the relevance of the local variables and you need to use BigInteger.valueOf(a).
Your method can be expressed in just one line:
public static BigInteger fact(int a) {
return a == 1 ? BigInteger.ONE : BigInteger.valueOf(a).multiply(fact(a - 1));
}
Find factorial with and without recursion of any number.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter no to find factorial :");
BigInteger inputNo1 = input.nextBigInteger();
System.out.println("With recursion " + inputNo1 + "! Factorial = " + (factorial(inputNo1.intValue())));
System.out.println("Without recursion " + inputNo1 + "! Factorial = " + (findFactorial(inputNo1)));
}
private static String findFactorial(BigInteger inputNo1) {
int counter;
BigInteger increment = new BigInteger("1");
BigInteger fact = new BigInteger("1");
for (counter = 1; counter <= inputNo1.longValueExact(); counter++) {
fact = fact.multiply(increment);
increment = increment.add(BigInteger.ONE);
}
return String.valueOf(fact);
}
public static BigInteger factorial(int number) {
if (number <= 1)
return BigInteger.ONE;
else
return factorial(number - 1).multiply(BigInteger.valueOf(number));
}
My solution for finding the factorial using recursion with the BigInteger Class
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.*;
import java.util.*;
class Main {
public static String factorial(int n,String s){
if(n>0){
BigInteger fact = new BigInteger(s);
fact = fact.multiply(new BigInteger(n + ""));
return factorial(n-1,fact.toString());
}
else{
return s.toString();
}
}
public static void main(String args[] ) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
int n = Integer.parseInt(line);
if(n==0)
System.out.println("Factorial is 0");
else{
String s = factorial(n,"1");
System.out.println("Factorial is " + s);
}
}
}
Output screenshot for the above code:
Take a look at this:
public static BigInteger fact(BigInteger a)
{
if(a.intValue()==1||a.intValue()==0)
{
return BigInteger.ONE;
}
else
{
return a.multiply(fact(a.subtract(BigInteger.ONE)));
}
}
The modifications are:
- Include 0!=1
- Because the function fact returns BigInteger the its argument must be BigInteger too!
Related
This is an homework problem
Is there a way tor reverse a number in Java without using any loops? The only solution I can think of is reversing it using String and then casting it back to an integer.
If you want to reverse a number withour using any loop you can use Recursion method call. Following program is doing same
public static void reverseMethod(int number) {
if (number < 10) {
System.out.println(number);
return;
} else {
System.out.print(number % 10);
reverseMethod(number / 10);
}
}
public static void main(String args[]) {
int num = 4567;
reverseMethod(num);
}
Even if you were to reverse the number by casting it into a String, you would still need a loop if you want the program to work when having ints of different sizes. If I were to make a method to reverse a number but could not do it with loops, I would probably do it with recursion (which still uses loops indirectly). The code will look something like this:
class Main {
public static void main(String[] args) {
String input = "1234"; // or scanner to take in input can be implemented
System.out.println(Integer.parseInt(reverseInt(input)));
}
public static String reverseInt(String x) {
if (x.length() == 1) {
return x;
} else {
return x.substring(x.length() - 1) + reverseInt(x.substring(0, x.length() - 1));
}
}
}
Hope this helps!
By using reverse() of StringBuilder:
int number = 1234;
String str = String.valueOf(number);
StringBuilder builder = new StringBuilder(str);
builder.reverse();
number = Integer.parseInt(builder.toString());
System.out.println(number);
will print:
4321
if you want reverse method without loop and recursion then use this code
int a=12345;
int b,c,d,e,f;
b=a%10;
c=a%100/10;
d=a%1000/100;
e=a%10000/1000;
f=a%100000/10000;
System.out.println(b+","+c+","+d+","+e+","+f);
you can go like :
public int reverse(int x) {
String o = "";
if (x < 0) {
x *= -1;
String s = Integer.toString(x);
o += "-";
o += new StringBuilder(s).reverse().toString();
}
else {
String s = Integer.toString(x);
o += new StringBuilder(s).reverse().toString();
}
try {
int out = Integer.parseInt(o);
//System.out.println(s);
return out; }
catch (NumberFormatException e) {
return 0;
}
}
This is a solution using recursive method call
public class Tester{
public static int findReverse(int num, int temp){
if(num==0){
return temp;
}else if(num<10){
return temp*10 + num; //up to this is stopping condition
}else{
temp = temp*10 + num%10;
return findReverse(num/10, temp);
}
}
public static void main(String args[]){
int num = 120021;
int reverseNum = findReverse(num, 0);
System.out.println(reverseNum);
if(num == reverseNum)
System.out.println(num +" is a palindrome!");
else
System.out.println(num +" is not a palindrome!");
}
}
This will be fast.
static int reverseNum(int num) {
StringBuilder sb = new StringBuilder(String.valueOf(num));
sb.reverse();
return Integer.parseInt(sb.toString());
}
I am attempting to prove that I am using tail recursion properly by restricting the size allocated to the thread stack using the java -Xss160M command. I am writing a simple tail recursion algorithm for finding the factorial of a really big numbers:
/*
*
*my Program
*
*/
import java.math.BigInteger;
public class TailFactorial {
private BigInteger factorial(BigInteger n, BigInteger acc) {
if (n.equals(BigInteger.ONE)) return acc;
else return factorial(n.subtract(BigInteger.ONE), n.multiply(acc));
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TailFactorial classs = new TailFactorial();
int num;
BigInteger bigNum = BigInteger.ONE;
boolean gTG = false;
String finalNumString = "";
String msg = "";
try {
num = Integer.parseInt(args[0]);
bigNum = BigInteger.valueOf(num);
msg = "fact("+String.valueOf(num)+") = ";
gTG = true;
}catch(Exception e) {
System.out.println("Could not get arguments, please make sure you are passing an integer");
gTG = false;
}
try {
if(gTG) {
BigInteger finalNum = classs.factorial(bigNum ,BigInteger.ONE);
System.out.println(String.valueOf(finalNum.bitCount()));
finalNumString = finalNum.toString();
//System.out.println( msg + finalNumString);
}
else {
System.out.print("Exiting");
}
}catch(StackOverflowError e) {
System.out.print("Not enough memory allocated to stack, try exicuting with java -Xss$bigger memory inserted here$ TrailFactorial");
}
catch(Exception e) {
System.out.print("Unrecoginzed error in finding factorial");
}
}
}
The code runs just fine, but I have to allocate 50M to the stack. When I run the current program, it displays the bit count of the result. When I find the factorial of one-hundred-thousand the bit count is 708,218, and I still have to use 50M. Can someone explain to me the meaning of the M? is it megabytes or bits? Am I not implementing tail-recursion properly?
As noted; Java doesn't support tail call recursion optimisation so for a large n value you will always run out of stack.
I suggest you use a simple loop if you want to avoid this.
public static BigInteger factorial(int n) {
BigInteger acc = BigInteger.ONE;
for (int i = 2; i <= n; i++)
acc = acc.multiply(BigInteger.valueOf(i));
return acc;
}
If you really, really want to use recursion, you can use divide and conquer
public static BigInteger factorial(int n) {
return product(1, n);
}
public static BigInteger product(int from, int to) {
if (from == to) return BigInteger.valueOf(from);
int mid = (from + to) >>> 1;
return product(from, mid).multiply(product(mid + 1, to));
}
This has a stack depth of log2(n) or a maximum of ~32.
BTW The following code
System.out.println(String.valueOf(finalNum.bitCount()));
finalNumString = finalNum.toString();
System.out.println( msg + finalNumString);
is the same as
System.out.println(finalNum.bitCount());
System.out.println(msg + finalNum);
Here is my code:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
import java.security.SecureRandom;
public class Solution {
static BigDecimal result;
static Double y = 0.0;
static int o;
static int[] factors = new int[1];
static int current = 0;
public static void main(String[] args) {
Scanner a1 = new Scanner(System.in);
int b = a1.nextInt();
o = b;
result = new BigDecimal(Integer.valueOf(b));
BigInteger N = new BigInteger(Integer.toString(b - 1));
factor(N);
boolean isPrimitive = true;
for (int i1 = 2; i1 < 10000;i1++) {
isPrimitive = true;
//System.out.println("Enter the value of a large prime no");
BigInteger value = new BigInteger(String.valueOf(o-1));
//System.out.println("\nEnter the value of alpha");
BigInteger checking = new BigInteger(String.valueOf(i1));
BigInteger bigValue = new BigInteger(String.valueOf(o));
for(int i=0;i<factors.length;i++)
{
BigInteger temp = checking.pow(factors[i]);
// System.out.println("checking "+i1+": "+temp+" mod "+o+" = " + (temp.mod(new BigInteger(String.valueOf(o)))));
if ((temp.mod(bigValue)).equals(BigInteger.ONE)) {
isPrimitive = false;
break;
}
}
if(isPrimitive) {
System.out.print(i1+" ");
break;
}
else{
//System.out.println("not primitive roots");
}
}
System.out.println(result.toBigInteger());
}
private final static BigInteger ZERO = new BigInteger("0");
private final static BigInteger ONE = new BigInteger("1");
private final static BigInteger TWO = new BigInteger("2");
private final static SecureRandom random = new SecureRandom();
public static BigInteger rho(BigInteger N) {
BigInteger divisor;
BigInteger c = new BigInteger(N.bitLength(), random);
BigInteger x = new BigInteger(N.bitLength(), random);
BigInteger xx = x;
// check divisibility by 2
if (N.mod(TWO).compareTo(ZERO) == 0) return TWO;
do {
x = x.multiply(x).mod(N).add(c).mod(N);
xx = xx.multiply(xx).mod(N).add(c).mod(N);
xx = xx.multiply(xx).mod(N).add(c).mod(N);
divisor = x.subtract(xx).gcd(N);
} while ((divisor.compareTo(ONE)) == 0);
return divisor;
}
public static void factor(BigInteger N) {
//System.out.println("result = "+result);
if (N.compareTo(ONE) == 0) return;
if (N.isProbablePrime(20)) {
// System.out.println("n = "+N);
if ((N.doubleValue() != (y)) &&N.doubleValue() != (1.0) ) {
// System.out.println("j = "+String.valueOf(1.0 - (1.0/(N.doubleValue()))));
BigDecimal j = new BigDecimal(String.valueOf(1.0 - (1.0/(N.doubleValue()))));
//System.out.println("result = " +result+" * "+j);
result = new BigDecimal(String.valueOf(result.doubleValue() * j.doubleValue()));
//System.out.println(result.multiply(j));
//System.out.println((String.valueOf(1.0 - (1.0/(N.doubleValue())))));
y = N.doubleValue();
if (current == factors.length) {
int[] temp = new int[factors.length+1];
for (int i = 0; i < factors.length;i++) {
temp[i] = factors[i];
}
factors = temp;
}
factors[current] = o/y.intValue();
// System.out.println(o+"/"+y.intValue());
current++;
//System.out.println("result = "+result);
}
return;
}
BigInteger divisor = rho(N);
factor(divisor);
factor(N.divide(divisor));
}
}
I am trying to find the first primitive root of a prime number, then the amount of primitive roots it has. Finding the amount is no problem for any number, but finding the first number is supposed to work for any number up to 1 billion on a certain system for on which other people have been successful. It works for all values up to around a million, but it doesn't work for 999994267. I don't know how I can possibly optimize this further. I have spent maybe 18 hours on this. I honestly can't figure this out. Any suggestions?
Math Explanation:
It takes the factors of the given number o, and tests every number from 2 if it's o/factor[1,2,...] is = 1, if none of o's factors are, it breaks and prints the number.
PS. It is possible, as many other people have done it on the same system.
Ok so thanks to #IgorNikolaev above in the comments of my question I have figured out my problem and solved it. To fully optimize a modPow operation you need to use modular arithmetic.
Here are some links he provided which greatly helped:
en.wikipedia.org/wiki/Modular_arithmetic
en.wikipedia.org/wiki/Modular_exponentiation
And here is the code I wrote based on those links:
private static BigInteger fastModPow(BigInteger base, BigInteger exponent, final BigInteger modulo) {
BigInteger result = BigInteger.ONE;
while (exponent.compareTo(BigInteger.ZERO) > 0) {
if (exponent.testBit(0))
result = (result.multiply(base)).mod(modulo);
exponent = exponent.shiftRight(1);
base = (base.multiply(base)).mod(modulo);
}
return result.mod(modulo);
}
As you will see in the first link, it sort-of "wraps around" to find the mod of a power.
Thanks for everyones help.
I am trying to find out 2 to the power n. I used recursive function for this.
My Code:
class TwoPowerN
{
static BigInteger twoPowern(BigInteger x, long y)
{
BigInteger temp = new BigInteger("1");
if( y == 0)
return new BigInteger("1");
temp.equals(twoPowern(x, y/2));
if (y%2 == 0)
return temp.multiply(temp);
else
return x.multiply(temp.multiply(temp));
}
public static void main(String args[]) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
int t = Integer.parseInt(br.readLine());
while(t>0)
{
long r = Long.parseLong(br.readLine());
BigInteger a = new BigInteger("2");
BigInteger ans=twoPowern(a,r);
pw.println(ans);
t--;
}
pw.close();
}
}
But I don't get the required result.
For cases 1 2 3 4 5 I am getting 2 1 2 1 2. A similar program(using similar function but with int) in 'C' works fine.
Can anyone explain what is the mistake?
I think that you need to assign the recursive result, rather than test for equality:
temp.equals(twoPowern(x, y/2)); // This is checking for equality
Should be
temp = twoPowern(x, y/2); // This is assigning the value
temp.equals(twoPowern(x, y/2));
is a conditional statement in java, not an assignment, so you aren't
storing the recursive value.
This is a lot simpler:
public class power2 {
public static long power2( int power)
{
if(power <= 0)
return 1;
return 2 * power2(power-1);
}
static BigInteger twoPowern(long y)
{
if( y == 0) {
return BigInteger.ONE;
}
return new BigInteger("2").multiply(twoPowern(y-1));
}
public static void main(String[] args)
{
for(int i = 0; i < 10; i++)
{
System.out.println("2^" + i + "," + power2(i));
System.out.println("2^" + i + "," + twoPowern(i));
}
}
}
Using regular longs, or BigInteger.
I'm trying to solve Project Euler problem #16, where I need to sum all the digits of 2^1000. I've gotten stuck dealing with such a big number. My program worked for any number below 10^16, but failed afterwards. This told me that my logic was correct. I went ahead and converted all variables and methods to BigDecimal, but now the program does not run properly. It compiles as it is and there is no error; it just does not terminate. Does anyone have an idea on where I went wrong here?
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Powerdigitsum {
private static final BigDecimal one = new BigDecimal("1");
private static final BigDecimal ten = new BigDecimal("10");
private static BigDecimal sumofDigits(BigDecimal n){
BigDecimal sum = new BigDecimal("0");
while(n.compareTo(one) == 1 || n.compareTo(one) == 0){
sum.add(n.remainder(ten));
n.divide(ten);
n = n.setScale(0, RoundingMode.FLOOR);
}
return sum;
}
public static void main(String[] args) {
final double the_number = Math.pow(2,1000);
final double test = 15;
final BigDecimal two_to_the_thousandth_power = new BigDecimal(test);
System.out.println(sumofDigits(two_to_the_thousandth_power));
}
}
Just use BigInteger properly:
BigInteger a = new BigInteger("2").pow(1000);
The whole method is kinda wrong. See this:
private static BigInteger sumOfDigits(BigInteger n) {
BigInteger sum = BigInteger.ZERO;
while (n.compareTo(BigInteger.ZERO) == 1) {
sum = sum.add(n.remainder(ten));
n = n.divide(ten);
}
return sum;
}
You needed to compare to zero, not one. And you need to assign the values for BigIntegers and BigDecimals, their methods do nothing on their own, the instances of those classes are immutable.
For integers, it's generally better to use BigInteger. The decimal part (that gets there from dividing) is just thrown away.
final double the_number = Math.pow(2,1000);
This won't work because the_number is not large enought to take the result. You need to convert the pow call to BigInteger:
BigInteger result = new BigInteger("2").pow(1000);
But be aware.. this can take some time..
Don't use the BigDecimal(double) constructor: it is limited by the double primitive type, which cannot represent 2^1000.
You can use a BigInteger. Something along these lines should work (probably suboptimal, but...):
public static void main(final String... args)
{
// 2^1000
final BigInteger oneTo2000 = BigInteger.ONE.shiftLeft(1000);
BigInteger digitSum = BigInteger.ZERO;
// We don't want to split against the empty string, the first element would be ""
for (final String digit: oneTo2000.toString().split("(?<=.)"))
digitSum = digitSum.add(new BigInteger(digit));
System.out.println(digitSum);
}
public class SumofDigitsPow {
public static void main(String[] args) {
//2(2^1000)
String temp = BigInteger.ONE.shiftLeft(1000).toString();
int sum = 0;
for(int i=0;i<temp.length();i++){
sum+= temp.charAt(i) - '0';
}
System.out.println(Integer.toString(sum));
}
}
java.math.BigInteger.shiftLeft(int n) method returns a BigInteger whose value is (this << n),So you can get the answer by using BigInteger and LeftShift Method
import java.math.BigInteger;
public class Problem16 {
public static void main(String[] args) {
BigInteger number2 = new BigInteger("2");
BigInteger number3 = new BigInteger("0");
number3 =number2.pow(1000);
String str = number3.toString();
BigInteger sum = new BigInteger("0");
for(int i=0; i<str.length(); i++)
{
char c= str.charAt(i);
int value = Character.getNumericValue(c);
BigInteger value2 = new BigInteger(Integer.toString(value));
sum =sum.add(value2) ;
}
System.out.println(sum);
}
}
IF YOU THINK BIGINTEGER IS CHEATING AND/OR don't feel like using it/learning how to use it, this algorithm is the way to go.
Think about how you would calculate 2^1000 by hand. You'd start with 2^1 and multiply by two repeatedly. Now notice that the number of digits of powers of two increase by 1 for AT LEAST every 3 powers (could be after 4 powers like with 1024 to 8192). So make a jagged 2D array like this
int a[][]= new int[1000][];
for(int i=0;i<1000;i++)
{
a[i]= new int[1+(i/3)];
}
Then initialize a[0][0] to 2. After this, you want to write a for loop such that each row is filled from the rightmost spot. So make two variables "digit" and "carry". Digit is the number that you will input into the row you're working on, and the carry is the one you're going to take to the next calculation and add to the product of 2 and whatever digit you're multiplying it with. Be careful with the order you update digit and carry and reinitialize them to zero after every calculation. I think the hardest part is coming up with the limits for the for loop, so that it fits with the every 3 powers thing. You can make this simpler by just making a triangular jagged array that increments by one every row. I did it like this though. Here's my whole code.
import java.util.*;
public class ProjectEuler16
{
public static void main(String[] args)
{
long t1=System.currentTimeMillis();
ProjectEuler16 obj = new ProjectEuler16();
System.out.println(obj.bigNumHandler());
long t2= System.currentTimeMillis();
System.out.println(t2-t1);
}
int bigNumHandler()
{
int a[][] = new int[1000][];
for(int i=0;i<1000;i++)
{
a[i]= new int[1+(i/3)];
}
a[0][0]=2;
for(int i=1;i<1000;i++)
{
int carry=0;
int digit=0;
int f=0;
if(i%3==0)
{
f=1;
}
for(int j=a[i-1].length-1+f;j>=0;j--)
{
if(j==0&f==1)
{
a[i][0]=carry;
}
else
{
digit=((2*a[i-1][j-f])+carry)%10;
carry=((2*a[i-1][j-f])+carry)/10;
a[i][j]=digit;
}
}
}
int sum=0;
for(int k=0;k<a[999].length;k++)
{
sum=sum+a[999][k];
}
return sum;
}
}
Note that the last row lists the digits for 2^1000.I think you can figure out how to sum the digits. The program took about 5 seconds to come up with the answer.
solution::::
import java.math.BigInteger;
public class PR9 {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
BigInteger zero=BigInteger.valueOf(0);
BigInteger ten=BigInteger.valueOf(10);
BigInteger sum=zero;
BigInteger a = new BigInteger("2").pow(1000);
while(a.compareTo(zero)>0){
sum=sum.add(a.mod(ten));
a=a.divide(ten);
}
System.out.println(sum);
}
}
output:::::
1366
import java.math.BigInteger;
public class P16 {
public static BigInteger digitSum(int n) {
BigInteger sum = BigInteger.ZERO;
BigInteger number = new BigInteger("2").pow(n);
while (number.compareTo(BigInteger.ZERO) == 1) {
BigInteger remainder = number.remainder(BigInteger.TEN);
sum = sum.add(remainder);
number = number.divide(BigInteger.TEN);
}
return sum;
}
public static void main(String[] args) {
final double START = System.nanoTime();
System.out.println(digitSum(Integer.parseInt(args[0])));
final double DURATION = System.nanoTime() - START;
System.out.println("Duration: " + DURATION / 1000000 + "ms.");
}
}
While there maybe a way of solving this problem without the use of BigIntegers, it is clear that they make the code run way faster.
Mine only took about 4ms to find an answer.