I'm building the DSA algorithm. But I had a problem when ranking BigInteger numbers with other BigInteger numbers. This is the formula I want to use:
v = ((g^u1 * y^u2) mod p) mod q
This is the code I made:
BigInteger v = g.pow(u1.intValue()).multiply(y.pow(u2.intValue())).mod(p).mod(q);
When running the script, the error is:
Exception in thread "main" java.lang.ArithmeticException: BigInteger would overflow supported range
at java.math.BigInteger.reportOverflow(Unknown Source)
at java.math.BigInteger.pow(Unknown Source)
at DSAVerifying.main(DSAVerifying.java:38)
To expand on my comment and because I could not find a duplicate: use modPow!
The problem here is that g^u1 (and y^u2) is REALLY large. But very often when dealing with powers in maths you have a mod statement following it and that simplifies stuff a lot: generally a ^ b mod c can be expressed as ((((a * a) mod c) * a) mod c) * a) mod c ..... (b times). And that is basically what modPow does, it applies the mod during the exponation. This will return the same number but will not overflow. They are mathematically identical, but one can be calculated by a computer with reasonable effort while the other cannot. It is up to you as the developer to be smart and simplify or rephrase the expression you want to solve in a way that a computer can properly handle.
BigInteger v = g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q);
Basically to compute (6 ^ 10 mod 7) you do not ever want to first calculate 6 ^ 10 and then apply the mod 7 but instead do 6 * 6 mod 7 = 36 mod 7 = 1 => 1 * 6 mod 7 = 6 => 6 * 6 mod 7 = 36 mod 7 = 1 => ... and you can see that the only values you deal with are 1 and 6 instead of 60466176 (which is 6^10).
Related
This question already has answers here:
Why does Java's hashCode() in String use 31 as a multiplier?
(13 answers)
Closed 2 years ago.
I have started learning Collections. So when we generate hashcode using eclipse below is the formula which is present in the method:
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((pin == null) ? 0 : pin.hashCode());
I have searched and found that since 31 is odd prime we use it while calculating hashcode. Multiplying by prime gives a good distribution of hashcodes.But haven't come across any concrete/layman explaination on why do we use the above formula and why exactly 31 is used. Can someone please help elaborate on how exactly does multiplying by 31 give a better distribution of hashcode?
from Joshua Bloch, Effective Java, Chapter 3, Item 9
The value 31 was chosen because it is an odd prime. If it were even and the multiplication overflowed, information would be lost, as multiplication by 2 is equivalent to shifting. The advantage of using a prime is less clear, but it is traditional. A nice property of 31 is that the multiplication can be replaced by a shift and a subtraction for better performance: 31 * i == (i << 5) - i. Modern VMs do this sort of optimization automatically.
Some words about multiplication can be replaced by a shift. Multiplying to 2 is pretty easy operations in binary algebra. You just need to shift the number to the left and add 0 to the end. 4*2 = b100 << 1 = b1000 = 8. If a factor is a power of 2, you need to shift the binary number by the power value. 4*8 = 4 * 2^3 = b100 << 3 = b100000 = 32.
Also the same logic works for dividing: 8/4 = 8/2^2 = b1000 >> 2 = b10 = 2
So this was a question on one of the challenges I came across in an online competition, a few days ago.
Question:
Accept two inputs.
A big number of N digits,
The number of questions Q to be asked.
In each of the question, you have to find if the number formed by the string between indices Li and Ri is divisible by 7 or not.
Input:
First line contains the number consisting on N digits. Next line contains Q, denoting the number of questions. Each of the next Q lines contains 2 integers Li and Ri.
Output:
For each question, print "YES" or "NO", if the number formed by the string between indices Li and Ri is divisible by 7.
Constraints:
1 ≤ N ≤ 105
1 ≤ Q ≤ 105
1 ≤ Li, Ri ≤ N
Sample Input:
357753
3
1 2
2 3
4 4
Sample Output:
YES
NO
YES
Explanation:
For the first query, number will be 35 which is clearly divisible by 7.
Time Limit: 1.0 sec for each input file.
Memory Limit: 256 MB
Source Limit: 1024 KB
My Approach:
Now according to the constraints, the maximum length of the number i.e. N can be upto 105. This big a number cannot be fitted into a numeric data structure and I am pretty sure thats not the efficient way to go about it.
First Try:
I thought of this algorithm to apply the generic rules of division to each individual digit of the number. This would work to check divisibility amongst any two numbers, in linear time, i.e. O(N).
static String isDivisibleBy(String theIndexedNumber, int divisiblityNo){
int moduloValue = 0;
for(int i = 0; i < theIndexedNumber.length(); i++){
moduloValue = moduloValue * 10;
moduloValue += Character.getNumericValue(theIndexedNumber.charAt(i));
moduloValue %= divisiblityNo;
}
if(moduloValue == 0){
return "YES";
} else{
return "NO";
}
}
But in this case, the algorithm has to also loop through all the values of Q, which can also be upto 105.
Therefore, the time taken to solve the problem becomes O(Q.N) which can also be considered as Quadratic time. Hence, this crossed the given time limit and was not efficient.
Second Try:
After that didn't work, I tried searching for a divisibility rule of 7. All the ones I found, involved calculations based on each individual digit of the number. Hence, that would again result in a Linear time algorithm. And hence, combined with the number of Questions, it would amount to Quadratic Time, i.e. O(Q.N)
I did find one algorithm named Pohlman–Mass method of divisibility by 7, which suggested
Using quick alternating additions and subtractions: 42,341,530
-> 530 − 341 = 189 + 42 = 231 -> 23 − (1×2) = 21 YES
But all that did was, make the time 1/3rd Q.N, which didn't help much.
Am I missing something here? Can anyone help me find a way to solve this efficiently?
Also, is there a chance this is a Dynamic Programming problem?
There are two ways to go through this problem.
1: Dynamic Programming Approach
Let the input be array of digits A[N].
Let N[L,R] be number formed by digits L to R.
Let another array be M[N] where M[i] = N[1,i] mod 7.
So M[i+1] = ((M[i] * 10) mod 7 + A[i+1] mod 7) mod 7
Pre-calculate array M.
Now consider the expression.
N[1,R] = N[1,L-1] * 10R-L+1 + N[L,R]
implies (N[1,R] mod 7) = (N[1,L-1] mod 7 * (10R-L+1mod 7)) + (N[L,R] mod 7)
implies N[L,R] mod 7 = (M[R] - M[L-1] * (10R-L+1 mod 7)) mod 7
N[L,R] mod 7 gives your answer and can be calculated in O(1) as all values on right of expression are already there.
For 10R-L+1 mod 7, you can pre-calculate modulo 7 for all powers of 10.
Time Complexity :
Precalculation O(N)
Overall O(Q) + O(N)
2: Divide and Conquer Approach
Its a segment tree solution.
On each tree node you store the mod 7 for the number formed by digits in that node.
And the expression given in first approach can be used to find the mod 7 of parent by combining the mod 7 values of two children.
The time complexity of this solution will be O(Q log N) + O(N log N)
Basically you want to be able to to calculate the mod 7 of any digits given the mod of the number at any point.
What you can do is to;
record the modulo at each point O(N) for time and space. Uses up to 100 KB of memory.
take the modulo at the two points and determine how much subtracting the digits before the start would make e.g. O(N) time and space (once not per loop)
e.g. between 2 and 3 inclusive
357 % 7 = 0
3 % 7 = 3 and 300 % 7 = 6 (the distance between the start and end)
and 0 != 6 so the number is not a multiple of 7.
between 4 and 4 inclusive
3577 % 7 == 0
357 % 7 = 0 and 0 * 10 % 7 = 0
as 0 == 0 it is a multiple of 7.
You first build a list of digits modulo 7 for each number starting with 0 offset (like in your case, 0%7, 3%7, 35%7, 357%7...) then for each case of (a,b) grab digits[a-1] and digits[b], then multiply digits[b] by 1-3-2-6-4-5 sequence of 10^X modulo 7 defined by (1+b-a)%6 and compare. If these are equal, return YES, otherwise return NO. A pseudocode:
readString(big);
Array a=[0]; // initial value
Array tens=[1,3,2,6,4,5]; // quick multiplier lookup table
int d=0;
int l=big.length;
for (int i=0;i<l;i++) {
int c=((int)big[i])-48; // '0' -> 0, and "big" has characters
d=(3*d+c)%7;
a.push(d); // add to tail
}
readInt(q);
for (i=0;i<q;i++) {
readInt(li);
readInt(ri); // get question
int left=(a[li-1]*tens[(1+ri-li)%6])%7;
if (left==a[ri]) print("YES"); else print("NO");
}
A test example:
247761901
1
5 9
61901 % 7=0. Calculating:
a = [0 2 3 2 6 3 3 4 5 2]
li = 5
ri = 9
left=(a[5-1]*tens[(1+9-5)%6])%7 = (6*5)%7 = 30%7 = 2
a[ri]=2
Answer: YES
There is XOR function in Java - a^b
For exemple: 5^3 = 6
Can you tell me inverse function? If I have 6 and 3 can i get range of numbers which include number 5?
The inverse is XOR!
If you have:
c = a^b;
You can get a or b back if you have the other value available:
a = c^b; // or b^c (order is not important)
b = c^a; // or a^c
For example if a = 5, b = 3 (and thus c = 6 as you mentioned) you get:
b=0011 (3) a=0101 (5)
c=0110 (6) XOR or c=0110 (6) XOR
---------- ----------
a=0101 (5) b=0011 (3)
The inverse of XOR is XOR itself.
I came across a similar problem on leetcode. Leetcode-1720
The inverse of XOR is XOR itself. For example if you take this operation :
3 ^ 4 = 7
The following statements are true :
4 ^ 7 = 3
3 ^ 7 = 4
Hopefully, this helps.
Inverse of a XOR is XOR itself.
For better reference and understanding u can refer to LeetCode 2433.
I have some problem with numerator, denumerator and modulo. 7 / 3 = 2.3333333333 gives me a modulo of 1!? Must be some wrong? I study a non-objective ground level course, so my code is simple and I have simplified the code below. (Some lines are in swedish)
Calling the method:
// Anropar metod och presenterar beräkning av ett bråktal utifrån täljare och nämnare
int numerator = 7;
int denumerator = 3;
System.out.println("Bråkberäkning med täljare " + numerator + " och nämnare " + denumerator + " ger " + fraction(numerator,denumerator));
And the method:
// Metod för beräkning av bråktal utifrån täljare och nämnare
public static String fraction(int numerator, int denumerator) {
// Beräkning
int resultat1 = numerator / denumerator;
int resultat2 = numerator % denumerator;
return Integer.toString(resultat1) + " rest " + Integer.toString(resultat2);
}
3 goes into 7 twice with 1 left over. The answer is supposed to be 1. That's what modulo means.
7 modulo 3 gives 1. Since 7 = 2*3 + 1.
7 % 3 = 1
Just as expected. If you want the .3333 you could take the modulo and devide it by your denominator to get 1 / 3 = 0.3333
Or do (7.0 / 3.0) % 1 = 0.3333
Ehm 7 % 3 = 1
What would you expect?
Given two positive numbers, a (the dividend) and n (the divisor), a modulo n (abbreviated as a mod n) can be thought of as the remainder, on division of a by n. For instance, the expression "5 mod 4" would evaluate to 1 because 5 divided by 4 leaves a remainder of 1, while "9 mod 3" would evaluate to 0 because the division of 9 by 3 leaves a remainder of 0; there is nothing to subtract from 9 after multiplying 3 times 3. (Notice that doing the division with a calculator won't show you the result referred to here by this operation, the quotient will be expressed as a decimal.) When either a or n is negative, this naive definition breaks down and programming languages differ in how these values are defined. Although typically performed with a and n both being integers, many computing systems allow other types of numeric operands.
More info : http://en.wikipedia.org/wiki/Modulo_operation
you didn't do a question!
And if your question is just:
"...gives me a modulo of 1!? Must be some wrong?"
No, it isn't, 7/3 = 2, and has a modulo of 1. Since (3 * 2) + 1 = 7.
You are using integer operands so you get an integer result. That's how the language works.
A modulo operator will give you the reminder of a division. Therefore, it is normal that you get the number 1 as a result.
Also, note that you are using integers... 7/3 != 2.3333333333.
One last thing, be careful with that code. A division by zero would make your program crash. ;)
% for ints does not give the decimal fraction but the remainder from the division. Here it is from 6 which is the highest multiplum of 2 lower than your number 7. 7-6 is 1.
I'm trying this simple calculation in a Java application:
System.out.println("b=" + (1 - 7 / 10));
Obviously I expect the output to be b=0.3, but I actually get b=1 instead.
What?! Why does this happen?
If I write:
System.out.println("b=" + (1 - 0.7));
I get the right result, which is b=0.3.
What's going wrong here?
You're using integer division.
Try 7.0/10 instead.
You've used integers in the expression 7/10, and integer 7 divided by integer 10 is zero.
What you're expecting is floating point division. Any of the following would evaluate the way you expected:
7.0 / 10
7 / 10.0
7.0 / 10.0
7 / (double) 10
Please do not take this as an answer to the question. It is not, but an advice related to exploiting the difference of int and float. I would have put this under a comment except that the answer box allows me to format this comment.
This feature has been used in every respectable programming language since the days of fortran (or earlier) - I must confess I was once a Fortran and Cobol punch card programmer.
As an example, integer division of 10/3 yields integer value 3 since an integer has no facility to hold fractional residual .3333.. .
One of the ways we (old time ancient programmers) had been using this feature is loop control.
Let's say we wish to print an array of 1000 strings, but we wish to insert a line break after every 15th string, to insert some prettyfying chars at the end of the line and at the beginning of the next line. We exploit this, given that integer k is the position of a string in that array.
int(k/15)*15 == k
is true only when k is divisible by 15, an occurrence at a frequency of every 15th cell. Which is akin to what my friend said about his grandfather's dead watch being accurate twice a day.
int(1/15) = 0 -> int(1/15)*15 = 0
int(2/15) = 0 -> int(2/15)*15 = 0
...
int(14/15) = 0 -> int(14/15)*15 = 0
int(15/15) = 1 -> int(15/15)*15 = 15
int(16/15) = 1 -> int(16/15)*15 = 15
int(17/15) = 1 -> int(17/15)*15 = 15
...
int(29/15) = 1 -> int(29/15)*15 = 15
int(30/15) = 2 -> int(30/15)*15 = 30
Therefore, the loop,
leftPrettyfy();
for(int k=0; k<sa.length; k++){
print(sa[k]);
int z = k + 1;
if ((z/15)*15 == z){
rightPrettyfy();
leftPrettyfy();
}
}
By varying k in a fanciful way in the loop, we could print a triangular printout
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
That is to demonstrate that, if you consider this a bug, this "bug" is a useful feature that we would not want to be removed from any of the various languages that we have used thus far.
I find letter identifiers to be more readable and more indicative of parsed type:
1 - 7f / 10
1 - 7 / 10f
or:
1 - 7d / 10
1 - 7 / 10d
In my case I was doing this:
double a = (double) (MAX_BANDWIDTH_SHARED_MB/(qCount+1));
Instead of the "correct" :
double a = (double)MAX_BANDWIDTH_SHARED_MB/(qCount+1);
Take attention with the parentheses !