Modulus on Combinatorials - java

Suppose a number n and we have to find sum of all combinatorials of n i.e. nC0+nC1+nC2+...+ nCn.
As result can be large so final answer should be sum%D (D=10^9+7).
Approach I used is-
long sum=0;
long combination=1;
for(int i=1;i<=n;i++){
combination=((combination*(n-i+1))/i)%D;
sum=(sum+combination)%D;
}
But this is not working.
Real Problem statement and code.Code is giving correct output till n=20.

You're supposed to mod the final output, not along every step of the way.
Also the numbers get very large so use BigInteger instead of long.
Here is my solution
http://ide.geeksforgeeks.org/Ew3Epn
Using the formula (2*n)!/(n!)^2
found here -> https://oeis.org/A000984

Related

How can I reduce iterations in for loop that takes to much time for execution?

Here, I am finding number of perfect square numbers in given range.
But I am dealing with 'for' loop execution that takes much time for execution.
The index/key traverses from two numbers, lets say A to B, and does some operation in for loop.
The problem arises when there's large difference between A and B (e.g. A = 2 & B = 100000)
Can u suggest how can I reduce or optimize the execution time?
Scanner in = new Scanner(System.in);
int A = in.nextInt();
int B = in.nextInt();
int cnt = 0;
for(int number =A ; number<= B; number++){
int sqrt = (int) Math.sqrt(number);
if(sqrt*sqrt == number) {
cnt++;
}
}
System.out.println(cnt);
Or is it because of Math class operations that takes too much time to execute?
Can you suggest any alternate approach to find the square numbers between given range?
Thanks in advance!
I found an alternate way to find the count of perfect square numbers between given range.
This can be simply achieve by using Math.floor and Math.ceil operations.
Math.floor(Math.sqrt(B)) - Math.ceil(Math.sqrt(A)) + 1
Thanks! :)
Instead of going through each number in the range and figuring out if its a perfect square, I would suggest the below
Find a square root of the start number and find the integer part of it.
Lets say start number is 5. So integer part of the square root will be 2.
Now do the same for the range end number
Lets say end range was 1000, so the integer part of its square root would be 31. Now iterate from 2+1 to 31 and keep printing its square. That would give you the perfect squares between the given range.
Instead of the if(sqrt * sqrt == number) you could also check whether the double returned by Math.srt(number) is a integer. The algorithm would than become as follows:
for(int number =A ; number<= B; number++){
if((Math.sqrt(number) % 1) == 0) {
cnt++;
}
}
Note: Haven't tried the code myself so might not work as I expect.
Regarding the question on how you can improve the performance. The checking on whether the number is perfect could be done in parallel by executing per number a task. The access to the counter has to be synchronized than, (to be on the safe side).

long to int conversion in java not working

I am working on a problem with big number's in java.
int temp =0;
long last = 218212982912L;
temp = (int) last%10;
last = last/10;
for the above line of code I get the
temp = -4
in the first iteration. I am not sure what is the problem. I have tried a lot of solution online available.
Put parentheses around last%10
The cast to int is being applied before the modulus operation
The last positive you can get is 2,147,483,647 and when you are explicitly converting a larger number to int, your will get unpleasant results but if you put extra parentheses like (int) (someLong % 10), first the long operation get executed (which results in smaller long value that fits int memory space) and then you can cast it to int without worry

Sum of Absolutes

I was trying to solve the simple problem posted on HackerRank.
https://www.hackerrank.com/contests/w16/challenges/sum-of-absolutes
I solved the problem, however its getting time out error to those with input array of size 100000. Could someone help me optimize this code below so it does not timeout.
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print outputto STDOUT. Your class should be named Solution. */
Scanner in = new Scanner(System.in);
int n= in.nextInt();
int q = in.nextInt();
in.nextLine();
int[] a = new int[n+1];
for(int i=1;i<=n;i++)
{
a[i]= in.nextInt();
}
for(int j=0;j<q;j++)
{
int l = in.nextInt();
int r = in.nextInt();
int sum=0;
for(int k=l;k<=r ;k++)
{
sum = Math.abs(sum+a[k]);
}
if(sum%2 == 0)
System.out.println("Even");
else
System.out.println("Odd");
}
}
I think you need to completely rethink your solution: You don;t actually need to work out the summation in order to establish if the result is odd or even.
The observation that adding two even numbers or two odd number gives you an even; and that adding an even and an odd give you an odd for all numbers (positive and negative) should be all you need.
Think about whether there's a shortcut that will give you the same odd/even answer. For example, -8 and 8 are both even while -3 and 3 are both odd. Do you really need to take an absolute value to determine if the sum is even or odd?
---Edit: Another thought or two---
First thought.
Please take a look at Bitwise and Bit Shift Operations. There are bitwise ways to figure out if the number is negative (namely: The high-order bit is 1). And there are bitwise ways to tell if the number is odd (namely: The low-order bit of a positive number is 1 and the low order bit of a negative number is 0).
--- Edit: Second thought---
Could you compress the array by not storing the input numbers, but instead the parity of those numbers? For example, you could use boolean[] isOdd or BitSet isOdd? You could store -7 in position i as isOdd[i] = true; or isOdd.set(i);. (Since BitSet and boolean both initialize to all false, you would not change the boolean or BitSet in position j if position j were even; see BitSet.) Then your answer would consist of counting the odds (or flipping a boolean or not'ing a bit) in the requested set and answering odd if the sum were odd (or false or 0) or even if the sum were even (or true or 1).
Why should you use a BitSet or boolean array? You can pack more information into less memory, making it easier for Java to find the space and leading to fewer page faults should you go over a page boundary.
I'm going to give you two hints. First, always look for needlessly repeated operations (spoiler: how many times do you do Math.abs on each value in the set?). And second, file IO is very expensive. Look for a way to use Scanner more efficiently.

Project Euler #8 in java

The challenge is listed here:
The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832.
73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450
Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?
I have written a code that works with the given 4 digit example, but doesn't work for 13 digits. I suspect there is some type of data overflow, but I am unsure. My super inefficient code is below.
public class Euler8 {
public static void main(String[]args){
String num = "/*number listed above*/";
int n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13;
long sum=0, newSum;
for(int n=0; n<=987; n++){
n1=Character.getNumericValue(num.charAt(n));
n2=Character.getNumericValue(num.charAt(n+1));
n3=Character.getNumericValue(num.charAt(n+2));
n4=Character.getNumericValue(num.charAt(n+3));
n5=Character.getNumericValue(num.charAt(n+4));
n6=Character.getNumericValue(num.charAt(n+5));
n7=Character.getNumericValue(num.charAt(n+6));
n8=Character.getNumericValue(num.charAt(n+7));
n9=Character.getNumericValue(num.charAt(n+8));
n10=Character.getNumericValue(num.charAt(n+9));
n11=Character.getNumericValue(num.charAt(n+10));
n12=Character.getNumericValue(num.charAt(n+11));
n13=Character.getNumericValue(num.charAt(n+12));
newSum= (long)(n1*n2*n3*n4*n5*n6*n7*n8*n9*n10*n11*n12*n13);
if(newSum>=sum)
sum=newSum;
}
System.out.println(sum);
}
}
My code outputs this number:
2091059712
Your code makes a cast to long too late: by the time the cast is performed, the multiplication has been completed in 32-bit integers, predictably causing an overflow.
Change the code as follows to fix the problem:
// newSum should be called newProd, because you use multiplication, not addition
newSum= ((long)n1)*n2*n3*n4*n5*n6*n7*n8*n9*n10*n11*n12*n13;
Note that your algorithm is not the most efficient: you could do it 13 times faster if you observe that the product for positions i+1..i+13 can be computed from the product for positions i..i+12 by dividing the value at position i and multiplying by the value at position i+13.
Of course you would have to be careful not to divide by zero. You can work around this by observing that any time you encounter a zero, the next 13 products would all be zero, so you could simply skip them, and move on to the next "train" of non-zeros.
The problem is that n1*n2*n3*n4*n5*n6*n7*n8*n9*n10*n11*n12*n13 overflows because:
they are all int variables, and
an int multiplied by an int gives an int.
The typecase to long is applied to the entire product, and (therefore) happens too late to cause the computations to be done with long arithmetic and avoid the overflow problem.
The simple solution to that particular problem is to declare the n variables as long. It is possible that #dasblinkelights' code (casting n1) is faster ... but you would need to benchmark it to be sure. And there are more significant optimizations than that.
I get the answer as 23514624000 . which is actually correct.
public class LargestProduct {
public static void main(String[]args) {
String s="7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
long k=0,l=13,ans=1,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13;
long Max_Num=0;
String[] result=new String[1000];
result=s.split("");
for(int i=0;i<=987;i++) {
n1=Integer.parseInt(result[i]);
n2=Integer.parseInt(result[i+1]);
n3=Integer.parseInt(result[i+2]);
n4=Integer.parseInt(result[i+3]);
n5=Integer.parseInt(result[i+4]);
n6=Integer.parseInt(result[i+5]);
n7=Integer.parseInt(result[i+6]);
n8=Integer.parseInt(result[i+7]);
n9=Integer.parseInt(result[i+8]);
n10=Integer.parseInt(result[i+9]);
n11=Integer.parseInt(result[i+10]);
n12=Integer.parseInt(result[i+11]);
n13=Integer.parseInt(result[i+12]);
ans=n1*n2*n3*n4*n5*n6*n7*n8*n9*n10*n11*n12*n13;
Max_Num=Math.max(Max_Num, ans);
}
System.out.println(Max_Num);
}
}

BigInteger.pow(BigInteger)?

I'm playing with numbers in Java, and want to see how big a number I can make. It is my understanding that BigInteger can hold a number of infinite size, so long as my computer has enough Memory to hold such a number, correct?
My problem is that BigInteger.pow accepts only an int, not another BigInteger, which means I can only use a number up to 2,147,483,647 as the exponent. Is it possible to use the BigInteger class as such?
BigInteger.pow(BigInteger)
Thanks.
You can write your own, using repeated squaring:
BigInteger pow(BigInteger base, BigInteger exponent) {
BigInteger result = BigInteger.ONE;
while (exponent.signum() > 0) {
if (exponent.testBit(0)) result = result.multiply(base);
base = base.multiply(base);
exponent = exponent.shiftRight(1);
}
return result;
}
might not work for negative bases or exponents.
You can only do this in Java by modular arithmetic, meaning you can do a a^b mod c, where a,b,c are BigInteger numbers.
This is done using:
BigInteger modPow(BigInteger exponent, BigInteger m)
Read the BigInteger.modPow documentation here.
The underlying implementation of BigInteger is limited to (2^31-1) * 32-bit values. which is almost 2^36 bits. You will need 8 GB of memory to store it and many times this to perform any operation on it like toString().
BTW: You will never be able to read such a number. If you tried to print it out it would take a life time to read it.
Please be sure to read the previous answers and comments and understand why this should not be attempted on a production level application. The following is a working solution that can be used for testing purposes only:
Exponent greater than or equal to 0
BigInteger pow(BigInteger base, BigInteger exponent) {
BigInteger result = BigInteger.ONE;
for (BigInteger i = BigInteger.ZERO; i.compareTo(exponent) != 0; i = i.add(BigInteger.ONE)) {
result = result.multiply(base);
}
return result;
}
This will work for both positive and negative bases. You might want to handle 0 to the power of 0 according to your needs, since that's technically undefined.
Exponent can be both positive or negative
BigDecimal allIntegersPow(BigInteger base, BigInteger exponent) {
if (BigInteger.ZERO.compareTo(exponent) > 0) {
return BigDecimal.ONE.divide(new BigDecimal(pow(base, exponent.negate())), 2, RoundingMode.HALF_UP);
}
return new BigDecimal(pow(base, exponent));
}
This re-uses the first method to return a BigDecimal with 2 decimal places, you can define the scale and rounding mode as per your needs.
Again, you should not do this in a real-life, production-level system.
java wont let you do BigInteger.Pow(BigInteger) but you can just put it to the max integer in a loop and see where a ArithmeticException is thrown or some other error due to running out of memory.
2^2,147,483,647 has at least 500000000 digit, in fact computing pow is NPC problem, [Pow is NPC in the length of input, 2 input (m,n) which they can be coded in O(logm + logn) and can take upto nlog(m) (at last the answer takes n log(m) space) which is not polynomial relation between input and computation size], there are some simple problems which are not easy in fact for example sqrt(2) is some kind of them, you can't specify true precision (all precisions), i.e BigDecimal says can compute all precisions but it can't (in fact) because no one solved this up to now.
I can suggest you make use of
BigInteger modPow(BigInteger exponent, BigInteger m)
Suppose you have BigInteger X, and BigInteger Y and you want to calculate BigInteger Z = X^Y.
Get a large Prime P >>>> X^Y and do Z = X.modPow(Y,P);
For anyone who stumbles upon this from the Groovy side of things, it is totally possible to pass a BigInteger to BigInteger.pow().
groovy> def a = 3G.pow(10G)
groovy> println a
groovy> println a.class
59049
class java.math.BigInteger
http://docs.groovy-lang.org/2.4.3/html/groovy-jdk/java/math/BigInteger.html#power%28java.math.BigInteger%29
Just use .intValue()
If your BigInteger is named BigValue2, then it would be BigValue2.intValue()
So to answer your question, it's
BigValue1.pow(BigValue2.intValue())

Categories

Resources