BigInteger Performance - java

public static BigInteger find(BigInteger A,BigInteger B)
{
BigInteger res=BigInteger.ONE;
for(BigInteger i=A;i.compareTo(B)!=0;i.add(BigInteger.ONE))
res=res.add(i);
/*for(BigInteger i=1;i.compareTo(B)!=0;i.add(BigInteger.ONE))
res=res.multiply(A);*/
return res;
}
my intention is to add any 2 numbers within the range., let's say 2 to 5(2+3+4+5) or A raise to B. I have other option to get it done within BigInteger, but can anybody say what's wrong with the above snippet in which
Its producing longggggggggggggggggggggggggggggggg strange number(instead of original) and
Its struggling/juggling so much to increment by 1 as it normally increment outside/without loop?
When will it reach just one increment(time or space factor/performance)?

The sum of all integers in a range can be calculated as the average value multiplied by the number of values, aka the "count".
If A and B are both inclusive, as indicated by the "2 to 5(2+3+4+5)" text in the question, then we have:
average = (A + B) / 2
count = B - A + 1
sum = count * average
= (B - A + 1) * ((A + B) / 2)
= (B - A + 1) * (B + A) / 2 // flipped A + B for the symmetry of it
In Java code, using BigInteger, that means:
public static BigInteger sumRangeInclusive(BigInteger A, BigInteger B) {
return B.subtract(A).add(BigInteger.ONE).multiply(B.add(A)).shiftRight(1);
}

It seems there is an issue with storing value of the loop variable after increment.
The sum of arithmetic progression should include both A and B:
public static BigInteger find(BigInteger A,BigInteger B)
{
BigInteger sum = BigInteger.ZERO;
for (BigInteger i = A; i.compareTo(B) <=0; i = i.add(BigInteger.ONE)) {
sum = sum.add(i);
}
return sum;
}
Tests:
System.out.println(find(new BigInteger("2"), BigInteger.valueOf(5)));
System.out.println(find(new BigInteger("200"), BigInteger.valueOf(500)));
Output:
14
105350

my option for A raises to B without generating multiple instances
public static BigInteger find(BigInteger A,BigInteger B)
{
BigInteger res=BigInteger.ONE;
int b=B.intValue();
for(int i=1;i<=b;i++)
res=res.multiply(A);
return res;
}

A better way to solve this would be by applying simple arithmetic. We know that:
Sum of natural numbers up to n = n * (n + 1) / 2
Sum of natural numbers from m to n = Sum of natural numbers up to n minus Sum of natural numbers up to m - 1 = n * (n + 1) / 2 - (m - 1) * (m - 1 + 1) / 2 = n * (n + 1) / 2 - (m - 1) * (m) / 2 = (n * (n + 1) - (m - 1) * m) / 2.
Demo:
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
System.out.println(find(BigInteger.valueOf(123456789), BigInteger.valueOf(987654321)));
}
public static BigInteger find(BigInteger A, BigInteger B) {
return B.multiply(B.add(BigInteger.ONE)).subtract(A.subtract(BigInteger.ONE).multiply(A))
.divide(BigInteger.TWO);
}
}
Output:
480109740075445815
What is wrong with your code?
The loop terminates when A becomes equal to B whereas it should terminate when A becomes greater than B. For this, you can use the terminating condition as i.compareTo(B.add(BigInteger.ONE)) != 0.
A BigInteger is an immutable arbitrary-precision integer. Therefore, i.add(BigInteger.ONE) won't modify the value of i. You need to assign the result to i i.e. i = i.add(BigInteger.ONE) in order to increment the value referenced by i by one.
You have started with a value 1 (i.e. BigInteger res=BigInteger.ONE) instead of 0.
Correct code:
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
System.out.println(find(BigInteger.valueOf(2), BigInteger.valueOf(5)));
}
public static BigInteger find(BigInteger A, BigInteger B) {
BigInteger res = BigInteger.ZERO;
for (BigInteger i = A; i.compareTo(B.add(BigInteger.ONE)) != 0; i = i.add(BigInteger.ONE))
res = res.add(i);
return res;
}
}
Output:
14
Although you can get the correct result after correcting your code this way, it's performance will be extremely bad.

Related

How to get the correct output in Modulo (10^9 + 7) format?

I am working on this code challenge:
Problem Description
Given 2 integers x and n, you have to calculate x
to the power of n, modulo 10^9+7 i.e. calculate (x^n) % (10^9+7).
In other words, you have to find the value when x is raised to the
power of n, and then modulo is taken with 10^9+7.
a%b means the remainder when a divides b. For instance, 5%3 = 2, as
when we divide 5 by 3, 2 is the remainder.
Note that 10^9 is also represented as 1e9.
Input format
One line of input containing two space separated
integers, x and n.
Output format Print the required answer.
Sample Input 1 100000000 2
Sample Output 1 930000007
Explanation 1 (10^8)^2 = 10^16
10^16 % (10^9+7) = 930000007
Constraints 0 <= x < 10^9
0 <= n < 10^5
Code
The following is my code:
import java.util.*;
class ModularExponentiation {
// NOTE: Please do not modify this function
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int n = sc.nextInt();
int ans = modularExponentiation(x, n);
System.out.println(ans);
}
// TODO: Implement this method
static int modularExponentiation(int x, int n) {
int M = 1000000007;
long a = (long) Math.pow(x, n);
long b = a%M;
return (int)b;
}
}
When I run my code, it succeeds for the sample test case and an edge case, but fails for 3 base cases. How do I make my code succeed all test cases?
Does this work?
public static int modularExponentiation(int x, int n) {
int modulo = 1000000007;
if (n == 0) {
return 1;
} else if (n == 1) {
return x % modulo;
} else if (n == -1) {
return 1 / x;
}
int p = modularExponentiation(x, n >> 1);
long product = ((long) p * p) % modulo;
return (int) (product * modularExponentiation(x, n & 1) % modulo);
}
Key points:
Math.pow(x,n) suffers from overflow and we can't compensate that overflow relying on result only, that is why initial idea of Math.pow(x,n) % modulo produces wrong results
We may notice that (x * x) % modulo == (x % modulo) * (x % modulo) % modulo, and it is safe to use long here as intermediate result because x % modulo < modulo and modulo * modulo < 2^63 - 1
We need to reconstruct the process, but naive approach that x^n is a product of n x's is too slow - it has O(N) time complexity, however we may notice that x^2k == (x^k)^2 and x^(2k+1) == x * (x^k)^2 - so we may use either recursion here or loop to achieve O(LogN) time complexity
alternative loop solution:
public static int modularExponentiation(int x, int n) {
int modulo = 1000000007;
long product = 1;
long p = x;
while (n != 0) {
if ((n & 1) == 1) {
product = product * p % modulo;
}
p = (p * p % modulo);
n >>= 1;
}
return (int) product;
}
If you have problem in C++ then , you can use
const unsigned int Mod=1e9+7;

Simple code doesn't output all required results

I have Java code that does the following:
1. Works with all combinations of integers a,b from 2 to 100 in sets of two. For instance, 2,2, 2,3,...,100,100. I just use two for loops for that.
2. For each set, checks whether the gcd of both integers is 1 (ignores sets where the gcd is 2 or more). I use the BigInteger Class because it has a method for that.
3. If the gcd is 1, check whether each of the two integers can be reconciled into a perfect power of base2 or more and exponent 3 or more. This is how I do that: For instance, let's consider the set 8,27. First, the code finds the max of the two. Then, for this set, the maximum power we can check for is Math.log10(27)/Math.log10(2) because the least the base can be is 2. This is just a trick from the field of mathematics. Hold that in variable powlim. I then use a for loop and Math.pow to check if all of the two integers have perfect nth roots like so;
for (double power = 3; power <= powlim; power++) {
double roota = Math.pow(a, 1.0 / power);
double rootb = Math.pow(b, 1.0 / power);
if ((Math.pow(Math.round(roota), power) == a) == true &&
(Math.pow(Math.round(rootb), power) == b) == true) {
if (a < b) {
System.out.println(a + "\t" + b);
}
}
The a<b condition makes sure that I don't get duplicate values such as both 8,27 and 27,8. For my purposes, the two are one and the same thing. Below is the entire code:
public static void main(String[] args) {
for (int a = 2; a <= 100; a++) {
for (int b = 2; b <= 100; b++) {
BigInteger newa = BigInteger.valueOf(a);
BigInteger newb = BigInteger.valueOf(b);
BigInteger thegcd = newa.gcd(newb);
if (thegcd.compareTo(BigInteger.ONE) == 0) {
double highest = Math.max(a, b);
double powlim = (Math.log10(highest) / Math.log10(2.0));
for (double power = 3; power <= powlim; power++) {
double roota = Math.pow(a, 1.0 / power);
double rootb = Math.pow(b, 1.0 / power);
if ((Math.pow(Math.round(roota), power) == a) == true
&& (Math.pow(Math.round(rootb), power) == b) == true {
if (a < b) {
System.out.println(a + "\t" + b);
}
}
}
}
}
}
}
So far so good. The code works fine. However, some few outputs that meet all the above criteria are ignored. For instance, when I run the above code I get;
8,27
16,81
27,64
What I don't understand is why a set like 8,81 is ignored. Its gcd is 1 and both of those integers can be expressed as perfect powers of base 2 or more and exponent 3 or more. 8 is 2^3 and 27 is 3^3. Why does this happen? Alternatively, it's fine if you provide your very own code that accomplishes the same task. I need to investigate how rare (or common) such sets are.
Math.pow(b, 1.0 / power); for 81 is 4.32
Then you round 4.32, and 4 at the power 3 is 64. 64 is not equal to 81.
What you should be doing is: Math.round(Math.pow(roota, power)) == a
Also, you need to iterate trough the powers of A and B separately, and check if the number can be rooted.
This means an additional check if the rounded-down value of the double is the same as the double. (Meaning the pow 1/3, 1/4 yields an integer result.)
public static void main(String[] args) {
for (int a = 2; a <= 100; a++) {
for (int b = 2; b <= 100; b++) {
BigInteger newa = BigInteger.valueOf(a);
BigInteger newb = BigInteger.valueOf(b);
BigInteger thegcd = newa.gcd(newb);
if (thegcd.compareTo(BigInteger.ONE) == 0) {
double highest = Math.max(a, b);
double powlim = (Math.log10(highest) / Math.log10(2.0));
for (double powerA = 3; powerA <= powlim; powerA++) {
double roota = Math.pow(a, 1.0 / powerA);
for (double powerB = 3; powerB <= powlim; powerB++) {
double rootb = Math.pow(b, 1.0 / powerB);
if (rootb == Math.floor(rootb) && roota == Math.floor(roota)) {
if ((Math.round(Math.pow(roota, powerA)) == a) && (Math.round(Math.pow(rootb, powerB)) == b)) {
if (a < b) {
System.out.println(a + "\t" + b);
}
}
}
}
}
}
}
}
}

LCM of the Two Numbers

Guys I found this code in online,used to find L.C.M of the two numbers but I couldn't understand the gcd() function.
when I try with a input a = 2,b = 3.It's showing 6 but when I do debugging myself I can't get the answer. I am struct here if (a == b) return a;
can you please help me to understand it's functionality. Please update with step by step functions
// Java program to find LCM of two numbers.
class Test
{
// Recursive method to return gcd of a and b
static int gcd(int a, int b)
{
// Everything divides 0
if (a == 0 || b == 0)
return 0;
// base case
if (a == b)
return a;
// a is greater
if (a > b)
return gcd(a-b, b);
return gcd(a, b-a);
}
// method to return LCM of two numbers
static int lcm(int a, int b)
{
return (a*b)/gcd(a, b);
}
// Driver method
public static void main(String[] args)
{
int a = 15, b = 20;
System.out.println("LCM of " + a +" and " + b + " is " + lcm(a, b));
}
}
From Wikipedia (https://en.wikipedia.org/wiki/Greatest_common_divisor):
In mathematics, the greatest common divisor (gcd) of two or more integers, which are not all zero, is the largest positive integer that divides each of the integers. For example, the gcd of 8 and 12 is 4.
Using Euclid's algorithm
Formally the algorithm can be described as:
gcd(a,0)=a
gcd(a,b)=gcd(b,a mod b)
where
a mod b = a - b [ a / b ]
If the arguments are both greater than zero then the algorithm can be written in more elementary terms as follows:
gcd(a,a)=a
gcd(a,b)=gcd(a-b,b), if a > b
gcd(a,b)=gcd(a,b-a), if b > a

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.

Calculating powers of integers

Is there any other way in Java to calculate a power of an integer?
I use Math.pow(a, b) now, but it returns a double, and that is usually a lot of work, and looks less clean when you just want to use ints (a power will then also always result in an int).
Is there something as simple as a**b like in Python?
When it's power of 2. Take in mind, that you can use simple and fast shift expression 1 << exponent
example:
22 = 1 << 2 = (int) Math.pow(2, 2)
210 = 1 << 10 = (int) Math.pow(2, 10)
For larger exponents (over 31) use long instead
232 = 1L << 32 = (long) Math.pow(2, 32)
btw. in Kotlin you have shl instead of << so
(java) 1L << 32 = 1L shl 32 (kotlin)
Integers are only 32 bits. This means that its max value is 2^31 -1. As you see, for very small numbers, you quickly have a result which can't be represented by an integer anymore. That's why Math.pow uses double.
If you want arbitrary integer precision, use BigInteger.pow. But it's of course less efficient.
Best the algorithm is based on the recursive power definition of a^b.
long pow (long a, int b)
{
if ( b == 0) return 1;
if ( b == 1) return a;
if (isEven( b )) return pow ( a * a, b/2); //even a=(a^2)^b/2
else return a * pow ( a * a, b/2); //odd a=a*(a^2)^b/2
}
Running time of the operation is O(logb).
Reference:More information
No, there is not something as short as a**b
Here is a simple loop, if you want to avoid doubles:
long result = 1;
for (int i = 1; i <= b; i++) {
result *= a;
}
If you want to use pow and convert the result in to integer, cast the result as follows:
int result = (int)Math.pow(a, b);
Google Guava has math utilities for integers.
IntMath
import java.util.*;
public class Power {
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
int num = 0;
int pow = 0;
int power = 0;
System.out.print("Enter number: ");
num = sc.nextInt();
System.out.print("Enter power: ");
pow = sc.nextInt();
System.out.print(power(num,pow));
}
public static int power(int a, int b)
{
int power = 1;
for(int c = 0; c < b; c++)
power *= a;
return power;
}
}
Guava's math libraries offer two methods that are useful when calculating exact integer powers:
pow(int b, int k) calculates b to the kth the power, and wraps on overflow
checkedPow(int b, int k) is identical except that it throws ArithmeticException on overflow
Personally checkedPow() meets most of my needs for integer exponentiation and is cleaner and safter than using the double versions and rounding, etc. In almost all the places I want a power function, overflow is an error (or impossible, but I want to be told if the impossible ever becomes possible).
If you want get a long result, you can just use the corresponding LongMath methods and pass int arguments.
Well you can simply use Math.pow(a,b) as you have used earlier and just convert its value by using (int) before it. Below could be used as an example to it.
int x = (int) Math.pow(a,b);
where a and b could be double or int values as you want.
This will simply convert its output to an integer value as you required.
A simple (no checks for overflow or for validity of arguments) implementation for the repeated-squaring algorithm for computing the power:
/** Compute a**p, assume result fits in a 32-bit signed integer */
int pow(int a, int p)
{
int res = 1;
int i1 = 31 - Integer.numberOfLeadingZeros(p); // highest bit index
for (int i = i1; i >= 0; --i) {
res *= res;
if ((p & (1<<i)) > 0)
res *= a;
}
return res;
}
The time complexity is logarithmic to exponent p (i.e. linear to the number of bits required to represent p).
I managed to modify(boundaries, even check, negative nums check) Qx__ answer. Use at your own risk. 0^-1, 0^-2 etc.. returns 0.
private static int pow(int x, int n) {
if (n == 0)
return 1;
if (n == 1)
return x;
if (n < 0) { // always 1^xx = 1 && 2^-1 (=0.5 --> ~ 1 )
if (x == 1 || (x == 2 && n == -1))
return 1;
else
return 0;
}
if ((n & 1) == 0) { //is even
long num = pow(x * x, n / 2);
if (num > Integer.MAX_VALUE) //check bounds
return Integer.MAX_VALUE;
return (int) num;
} else {
long num = x * pow(x * x, n / 2);
if (num > Integer.MAX_VALUE) //check bounds
return Integer.MAX_VALUE;
return (int) num;
}
}
base is the number that you want to power up, n is the power, we return 1 if n is 0, and we return the base if the n is 1, if the conditions are not met, we use the formula base*(powerN(base,n-1)) eg: 2 raised to to using this formula is : 2(base)*2(powerN(base,n-1)).
public int power(int base, int n){
return n == 0 ? 1 : (n == 1 ? base : base*(power(base,n-1)));
}
There some issues with pow method:
We can replace (y & 1) == 0; with y % 2 == 0
bitwise operations always are faster.
Your code always decrements y and performs extra multiplication, including the cases when y is even. It's better to put this part into else clause.
public static long pow(long x, int y) {
long result = 1;
while (y > 0) {
if ((y & 1) == 0) {
x *= x;
y >>>= 1;
} else {
result *= x;
y--;
}
}
return result;
}
Use the below logic to calculate the n power of a.
Normally if we want to calculate n power of a. We will multiply 'a' by n number of times.Time complexity of this approach will be O(n)
Split the power n by 2, calculate Exponentattion = multiply 'a' till n/2 only. Double the value. Now the Time Complexity is reduced to O(n/2).
public int calculatePower1(int a, int b) {
if (b == 0) {
return 1;
}
int val = (b % 2 == 0) ? (b / 2) : (b - 1) / 2;
int temp = 1;
for (int i = 1; i <= val; i++) {
temp *= a;
}
if (b % 2 == 0) {
return temp * temp;
} else {
return a * temp * temp;
}
}
Apache has ArithmeticUtils.pow(int k, int e).
import java.util.Scanner;
class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
try {
long x = sc.nextLong();
System.out.println(x + " can be fitted in:");
if (x >= -128 && x <= 127) {
System.out.println("* byte");
}
if (x >= -32768 && x <= 32767) {
//Complete the code
System.out.println("* short");
System.out.println("* int");
System.out.println("* long");
} else if (x >= -Math.pow(2, 31) && x <= Math.pow(2, 31) - 1) {
System.out.println("* int");
System.out.println("* long");
} else {
System.out.println("* long");
}
} catch (Exception e) {
System.out.println(sc.next() + " can't be fitted anywhere.");
}
}
}
}
int arguments are acceptable when there is a double paramter. So Math.pow(a,b) will work for int arguments. It returns double you just need to cast to int.
int i = (int) Math.pow(3,10);
Without using pow function and +ve and -ve pow values.
public class PowFunction {
public static void main(String[] args) {
int x = 5;
int y = -3;
System.out.println( x + " raised to the power of " + y + " is " + Math.pow(x,y));
float temp =1;
if(y>0){
for(;y>0;y--){
temp = temp*x;
}
} else {
for(;y<0;y++){
temp = temp*x;
}
temp = 1/temp;
}
System.out.println("power value without using pow method. :: "+temp);
}
}
Unlike Python (where powers can be calculated by a**b) , JAVA has no such shortcut way of accomplishing the result of the power of two numbers.
Java has function named pow in the Math class, which returns a Double value
double pow(double base, double exponent)
But you can also calculate powers of integer using the same function. In the following program I did the same and finally I am converting the result into an integer (typecasting). Follow the example:
import java.util.*;
import java.lang.*; // CONTAINS THE Math library
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n= sc.nextInt(); // Accept integer n
int m = sc.nextInt(); // Accept integer m
int ans = (int) Math.pow(n,m); // Calculates n ^ m
System.out.println(ans); // prints answers
}
}
Alternatively,
The java.math.BigInteger.pow(int exponent) returns a BigInteger whose value is (this^exponent). The exponent is an integer rather than a BigInteger. Example:
import java.math.*;
public class BigIntegerDemo {
public static void main(String[] args) {
BigInteger bi1, bi2; // create 2 BigInteger objects
int exponent = 2; // create and assign value to exponent
// assign value to bi1
bi1 = new BigInteger("6");
// perform pow operation on bi1 using exponent
bi2 = bi1.pow(exponent);
String str = "Result is " + bi1 + "^" +exponent+ " = " +bi2;
// print bi2 value
System.out.println( str );
}
}

Categories