Find the number modulo [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a question. I need to solve this problem: 3 ^ 54 mod 17 =? (3 to 54 degrees modulo 17 - which will be equal to?). Just please write with the maximum explanation. How did you find this huge number 3 ^ 54, how to get the module. Thank you very much in advance!!!

Have a look at this two equivalent equations:
c mod m = (a ⋅ b) mod m
c mod m = [(a mod m) ⋅ (b mod m)] mod m
Knowing this you can compute 3 ^ 54 mod 17 very efficient:
3 ^ 54 mod 17 =
3 ^ 27 * 3 ^ 27 mod 17 =
(3 ^ 27 mod 17 * 3 ^ 27 mod 17) mod 17 =
...
Know we can calc the modulo very fast. But how can we divide c fast?
This can be handled by the idea of "Exponentiation by squaring".
x^n = x(x^2)^((n-1)/2) if n is odd
x^n = (x^2)^(n/2) if n is even
An algorithm that uses this techniques is called "Fast modular exponentiation"
int power(int x, int y, int p){
int res = 1;
x = x % p;
while (y > 0){
if (y % 2 == 0)
res = (res*x) % p;
y /= 2;
x = (x*x) % p;
}
return res;
}

We know that 3 and 17 are coprime (indeed, both are prime, but that's not required). Because of this, we know that 3 is a generate w.r.t. multiplication for the group of integers modulo 17. That is, for any value b between 1 and 16, inclusive, there is some a such that 3^a = b (mod 17). The only way that is possible is if 3^a gives unique values modulo 17 at least 16 times in a row (for 3^0, 3^1, ..., 3^15). Thus, it turns out that 3^16 = 1 (mod 17) and, generally, a^(b-1) = 1 (mod b) whenever a and b are coprime.
This observation will get you down to something with an exponent less than your modulus minus one. Again, it requires that the base and the modulus be coprime, but it's the case in your question and it is a case of interest typically speaking.
More generally, you can always just try multiplying the base by itself a number of times no greater than the modulus and you are bound to find a cycle. Determine the cycle length and offset in the cycle (if any) and you can work out something a lot like what we did above. For instance, if we have 2^103 = ? (mod 10), what can we do? We see 2, 2*2 = 4, 2*2*2 = 8, 2*2*2*2 = 16 = 6 (mod 10), 2*2*2*2*2 = 32 = 2 (mod 10; we have already hit a cycle so we know this repeats forever. Since 2^5 = 2^1 (mod 10), we can rewrite 2^103 as (2^5)^20 * 2^3 = 2^20 * 2^3 = (2^5)^4 * 2^3 = 2^4 * 2^ = 2^7 = 2^5 * 2^2 = 2 * 2^2 = 2^3 (mod 10), thus 8.
Finally, if you find a 0 as you're doing the above, just stop; the answer will be zero forever after. For instance, 2^102938210 = ??? (mod 8) has the answer 0 since we get 2^1 = 2, 2^2 = 4, 2^3 = 8 = 0 (mod 8).

Related

Binary arithmetic: why hash%n is equivalent to hash&(n-1)?

I have been studying Java HashMap source code, the part of it which decides in what bucket to put an object and saw this change in Java 7 (8) as compared to Java 6.
Additionally I conducted numerous experiments and both expressions yeild the same result:
hash % n
and
hash & (n - 1)
where n - the array length that must be power of 2.
I just cannot figure out why is it true? Is there any theorem or some math laws that prove these statement are equal? Basically I want to understand the inference and prove the equivalence of those two statements.
PS. If n is not a power of 2 number, the equivalence breaks immedeately.
If n is a power of two that mean its binary representation is 10000....,
n-1 for that matter is 1111111... with one less digit.
That means that binary &-ing with (n-1) preserves just exactly the number of bits in k that n-1 has set.
Example n = 8: 1000, n-1 = 7: 111
&-ing for example k = 201: 11001001
k % n = k & (n-1) = 11001001 & 111 = 001 = 1.
%-ing with a power of 2 means that in binary you just strip everything away that is above (including) the only set bit: for n = 8 that means stripping everything over (including) the 4th bit. And that is exactly what the &-ing does at well.
A side effect is that using & is commutative: hash & (n - 1) is equivalent to (n - 1) & hash which is not true for %, the jdk source code in many places uses the later, e.g. in getNode
Think about the bits in (n - 1) if n is a power of 2 (or ((1 << i) - 1), if you want to simplify the constraint on n):
If n is, say, 16 (= 1 << 4), then n - 1 is 15, and the bit representation of 15 and 16 (as 32-bit ints) are:
1 = 00000000000000000000000000000001 // Shift by 4 to get...
16 = 00000000000000000000000000010000 // Subtract 1 to get...
15 = 00000000000000000000000000001111
So just the lowest 4 bits are set in 15. If you & this with another int, it will only allow bits in the last 4 bits of that number to be set in the result, so the value will only be in the range 0-15, so it's like doing % 16.
However, note that this equivalence doesn't hold for a negative first operand:
System.out.println(-1 % 2); // -1
System.out.println(-1 & (2-1)); // 1
Ideone demo
The arithmetic rule for integer / and % is:
x*(y/x) + (y%x) = y
What about a negative hash -4 and a positive n 8?
8*0 + (-4%8) = -4
Hence modulo maintains the sign.
-4 % 8 = -4
-4 & 7 = 4
Or:
int t = hash%n;
if (t < 0) {
t += n;
}
assert t == (hash & (n-1));
So in the earlier java with %n hash had to be positive to begin with.
Now hash may be negative, more solid and better hashing.
So that was a sound reason for this subtle change in java source code.
Background:
2n is a 1 followed by n-1 0s (in binary).
2n - 1 is n-1 1s.
Hence for n being a positive power of 2, and some positive number h:
h % n == h & (n-1)
Another usage is to count bits in an int. The class Integer has just such a function.
int bits = 0;
while (x != 0) {
x &= x - 1;
++bits;
}

Find the greatest odd number with a limited number of bits

I was trying to solve this question but the automated judge is returning "time limit exceeded" (TLE).
On the occasion of Valentine Day , Adam and Eve went on to take part in a competition.They cleared all rounds and got into the finals. In the final round, Adam is given a even number N and an integer K and he has to find the greatest odd number M less than N such that the sum of digits in binary representation of M is atmost K.
Input format:
For each test case you are given an even number N and an integer K
Output format:
For each test case, output the integer M if it exists, else print -1
Constraints:
1 &leq; T &leq; 104
2 &leq; N &leq; 109
0 &leq; K &leq; 30
Sample input:
2
10 2
6 1
Sample output:
9
1
This is what I have done so far.
static long play(long n, int k){
if(k==0) return -1;
if(k==1) return 1;
long m=n-1;
while(m>0){
long value=Long.bitCount(m); //built in function to count bits
if(value<=k ){
return m;
}
m=m-2;
}
return -1;
}
public void solve(InputReader in, OutputWriter out) {
long start=System.currentTimeMillis();
int t=in.readInt();
while(t-->0){
long n=in.readLong();
int k=in.readInt();
long result=play(n,k);
out.printLine(result);
}
long end=System.currentTimeMillis();
out.printLine((end-start)/1000d+"ms");
}
}
According to updated question N can be between 2 and 10^9. You're starting with N-1 and looping down by 2, so you get up to about 10^9 / 2 iterations of the loop. Not good.
Starting with M = N - 1 is good. And using bitCount(M) is good, to get started. If the initial bitcount is <= K you're done.
But if it's not, do not loop with step -2.
See the number in your mind as binary, e.g. 110101011. Bit count is 6. Let's say K is 4, that means you have to remove 2 bits. Right-most bit must stay on, and you want largest number, so clear the two second-last 1-bits. Result: 110100001.
Now, you figure out how to write that. And do it without converting to text.
Note: With N <= 10^9, it will fit in an int. No need for long.
You'll have to perform bitwise operations to compute the answer quickly. Let me give you a few hints.
The number 1 is the same in binary and decimal notation: 12 = 110
To make the number 102 = 210, shift 1 to the left by one position. In Java and many other languages, we can write this:
(1 << 1) == 2
To make the binary number 1002 = 410, shift 1 to the left by two positions:
(1 << 2) == 4
To make the binary number 10002 = 810 shift 1 to the left by three positions:
(1 << 3) == 8
You get the idea.
To see if a bit at a certain position is 1 or 0, use &, the bitwise AND operator. For example, we can determine that 510 = 1012 has a 1 at the third most significant bit, a 0 at the second most significant bit, and a 1 at the least significant bit:
5 & (1 << 2) != 0
5 & (1 << 1) == 0
5 & (1 << 0) != 0
To set a bit to 0, use ^, the bitwise XOR operator. For example, we can set the second most significant bit of 710 = 1112 to 0 and thus obtain 510 = 1012:
7 ^ (1 << 1) == 5
As the answer is odd,
let ans = 1, here we use 1 bit so k = k - 1;
Now binary representation of ans is
ans(binary) = 00000000000000000000000000000001
while(k > 0):
make 30th position set
ans(binary) = 01000000000000000000000000000001
if(ans(decimal) < N):
k -= 1
else:
reset 30th position
ans(binary) = 00000000000000000000000000000001
Do the same from 29th to 1st position

Can someone explain the following method that is used to find the length of the repeating cycle or period of a repeating decimal?

After reading information off the Wikipedia page for repeating decimals, I have found a way to find the number of digits in the repeating part of a decimal.
For example,
1/3 = 0.333333333333333333333333333333... so the result is 1 digit.
1/7 = 0.142857142857142857142857142857... so the result is 6 digits.
However, my method (in Java) did not work for 1/6 which should yield 1 because:
1/6 = 0.1666... so the result is 1 digit despite the non-repeating part of the decimal.
I have found a solution that works (credit to Nayuki Minase).
private static int getCycleLength(int n)
{
Map<Integer,Integer> stateToIter = new HashMap<Integer,Integer>();
int state = 1;
int iter = 0;
while (!stateToIter.containsKey(state))
{
stateToIter.put(state, iter);
state = state * 10 % n;
iter++;
}
System.out.println(iter + " - " + stateToIter.get(state));
return iter - stateToIter.get(state);
}
Can someone please explain to me how this algorithm works? Thank you.
Nayuki here. The code is from Project Euler p026.java. Let me explain what's going on.
The main idea is that we simulate long division and detect when the remainder starts repeating. Let's illustrate with an example of computing 1/7.
0.142857...
-------------
7 | 1.000000000
7
---
30
28
--
20
14
--
60
56
--
40
35
--
50
49
--
10
...
To perform long division, we perform these steps:
Set divisor = 7. Set dividend = 1. (We are computing 1/7.)
----
7 | 1
How many times does the divisor go into the dividend? Let this be k. Append this digit to the quotient.
0
---
7 | 1
Subtract k × divisor from the dividend. This is the remainder.
0
---
7 | 1
-0
--
1
Shift in a new digit on the right side. In our case, it's an infinite decimal of zeros. This is equivalent to multiplying the dividend by 10.
0
---
7 | 1.0
-0
--
10
Go to step 2 and repeat infinitely.
0.1
-----
7 | 1.0
-0
--
10
-7
--
3
...
We update the dividend in every iteration of long division. If the dividend takes on a value that it previously did, then it will generate the same decimal digits.
Now, in code:
// Step 1
int divisor = 7;
int dividend = 1;
while (true) {
// Step 2
int k = dividend / divisor; // Floor
// Step 3
dividend -= k * divisor;
// Step 4
dividend *= 10;
}
With a bit of math, steps 2 and 3 can be combined as dividend %= divisor;. Furthermore, this can be combined with step 4 to get dividend = dividend % divisor * 10;.
The map keeps track of the first time each dividend state was seen. In our example:
The remainder 1 was seen at iteration 0.
The remainder 3 was seen at iteration 1.
The remainder 2 was seen at iteration 2.
The remainder 6 was seen at iteration 3.
The remainder 4 was seen at iteration 4.
The remainder 5 was seen at iteration 5.
The remainder 1 was seen at iteration 6.
The state at iteration 6 is the same as the state at iteration 0. Furthermore, this is the shortest cycle. Hence, the cycle length is 6 − 0 = 6.
So in this algorithm this line is the key.
while(!stateToIter.containsKey(state))
It is breaking the program when it found a repetitive state. Now finding a repetitive state means we are detecting a repeating cycle. Lets go through the problem, say we have to find out for 6.
The way we do 1 / 6 is
Problem :6 | 1 | Result = ?
Step 1:
Add 0. in the result and multiply 1 with 10
6 | 10 | 0.
Iteration
Step 2:
Do the division
6 | 10 | 0.1
6
-----
4 [Mod]
Iteration = 0
Step 3:
Multiply mod with 10 and carry on
6 | 10 | 0.16
6
-----
40
36
-----
04 [Mod]
Iteration = 1
Now we find a repeating mod so now matter how far we go we always get 4 as mod and our result will be 0.166666.. and so on so our repeating cycle will be 1 which is our iteration.
When conventing to decimal you progressively multiply the value you have by 10 until you either have 0 (no more to write) or give up (you have reached the limit of your precision)
Once you have the same value you are working on again, you will repeat the same digits from that point. What the method does is find when you get a repeating values and computes how long it have been since you first saw it (the length of the repeating cycle)
BTW Another solution to this problem which avoids using a Map. Any repeating sequence must be a multiple of 1/9 or 1/99 or 1/999 or 1/9999 etc. This finds how many nines is required for the divisor to be a factor. This is the point at which it repeats.
public static void main(String... args) throws IOException {
for (int i = 3; i < 100; i++) {
System.out.println("i: " + i + " f: " + 1.0 / i + " repeat: " + getRepeatingCount(i));
}
}
public static final BigInteger TEN_TO_19 = BigInteger.TEN.pow(19);
public static int getRepeatingCount(int divisor) {
if (divisor <= 0) throw new IllegalArgumentException();
while (divisor % 2 == 0) divisor /= 2;
while (divisor % 5 == 0) divisor /= 5;
int count = 1;
if (divisor == 1) return 0;
for (long l = 10; l > 0; l *= 10) {
long nines = l - 1;
if (nines % divisor == 0)
return count;
count++;
}
for(BigInteger bi = TEN_TO_19; ; bi = bi.multiply(BigInteger.TEN)) {
BigInteger nines = bi.subtract(BigInteger.ONE);
if (nines.mod(BigInteger.valueOf(divisor)).equals(BigInteger.ZERO))
return count;
count++;
}
}

Linear Recurrence for very large n

I was trying to solve this problem on SPOJ (http://www.spoj.pl/problems/REC/)
F(n) = a*F(n-1) + b where we have to find F(n) Mod (m)
where
0 <= a, b, n <= 10^100
1 <= M <= 100000
F(0)=1
I am trying to solve it with BigInteger in JAVA but if I run a loop from 0 to n its getting TLE. How could I solve this problem? Can anyone give some hint? Don't post the solution. I want hint on how to solve it efficiently.
Note that the pattern of residues mod (m) should have a repeating pattern in a linear recurrence, and with length <= m by the pigeonhole principle. You need only calculate the first m entries, then figure out which of those entries will apply to F(n) for the actual value of n.
It also helps to solve a simpler problem. Let's pick really small values, say a=2, b=1, m=5, n=1000.
F(0) = 1
F(1) = 2*F(0) + 1 = 2*1 + 1 = 3 -> 3 Mod 5 = 3
F(2) = 2*F(1) + 1 = 2*3 + 1 = 7 -> 7 Mod 5 = 2
F(3) = 2*F(2) + 1 = 2*7 + 1 = 15 -> 15 Mod 5 = 0
F(4) = 2*F(3) + 1 = 2*15 + 1 = 31 -> 31 Mod 5 = 1
F(5) = 2*F(4) + 1 = 2*31 + 1 = 63 -> 63 Mod 5 = 3
etc.
Notice that the residues are [1, 3, 2, 0, 1, 3, ...], which will repeat forever. So from this example, how would you determine F(1000) Mod 5 without looping all the way to the 1000th entry?
First, I'll tell you how to solve a simpler problem. Suppose that b is zero. Then you just need to calculate an mod M. Instead of multiplying n-1 times, use a divide-and-conquer technique:
// Requires n >= 0 and M > 0.
int modularPower(int a, int n, int M) {
if (n == 0)
return 1;
int result = modularPower(a, n / 2, M);
result = (result * result) % M;
if (n % 2 != 0)
result = (result * a) % M;
return result;
}
So you can calculate an in terms of afloor(n/2), then square that, and multiply by a again if n is odd.
To solve your problem, first define the function f(x) = (a x + b) (mod M). You need to calculate fn(1), which is applying f n times to the initial value 1. So you can use divide-and-conquer like the previous problem. Luckily, the composition of two linear functions is also linear. You can represent a linear function by three integers (the two constants and the modulus). Write a function that takes a linear function and an exponent and returns the function composed that many times.

I need some help with a Java recursion problems

This is my first problem:
gcd(x,y)
if (x < y)
gcd(y,x)
else
if (y = 0)
return x
else
return gcd(y, x mod y)
This is my second problem:
public static int Test2(int x, int y) {
if (x > y) {
return 10;
} else {
return Test2(x-5, y+5) + 5;
}
}
The question is: What is returned for gcd(84, 21)?
a. 84
b. 21
c. 3 (This is the correct answer)
d. 10
X equals 84 and y equals 21. So I run them through the Algorithm class. 84 is not less than 21 so I skip that if statement. 84 is not equal so I skip that statement. I go to return gcd(y, x mod y). I don’t understand what is mod and how do you figure out what it means?
Second problem!
Question: What is returned for Test2(18,5)?
A. 5
B. 10
I choose ten , because x is greater than y and when processed to the if statement. It returns a value of ten. The if statements does run anything but the return statement.
C. 15 The answer is 15.
D. 20
mod is the modulo function. It's the rest when when you divide two integers. For example,
1 mod 3 = 1
2 mod 3 = 2
3 mod 3 = 0
4 mod 3 = 1
10 mod 4 = 2
10 is the correct answer for the second question, your argument is correct.
The modulo operator returns the remainder of a divison operation. e.g. 3 mod 2 = 1 since 1 is the remainder. % is commonly used as the symbol for mod. In this example 84 mod 21 equals 0 since 21 divides evenly into 84 four times.
x mod y is not valid Java, x % y is and it means modulo; that what if left after an integer division of x by y.
Btw, what do you mean with this is the answer and the answer is 15? Better to think the problem through and explain your own answer.

Categories

Resources