I have read several answers here on SO and on the web about choosing a good hash table length and that it should be a prime to reduce collisions and to uniformly distribute the keys across the hash table.
Though there are a lot of answers, I couldn't find a satisfying proof, and I didn't understand the explanations I found.
So if we have a key k and a hash table of length n and we do k % n = i to find the index i of a bucket in a hash table, we say that n should be a prime in order to minimize the number of collisions and to better distribute the keys across the hash table.
But why? Here is my attempt to prove it. It is going to be quite long and a bit pedantic, but please bear with me and try to read till the end.
I will start by making the following assumptions:
For every key k of the set of keys K, we can have a k which is either even or odd. A key is an integer, either even (k = 2x) or odd (k = 2x + 1).
For every n we may choose, n also can either be even (n = 2y) or odd (n = 2y + 1).
If we add an even number to another even number, we get an even number (2x + 2y = 2(x + y)). Likewise, if we add an odd number to another odd number, we still get an even number
((2x + 1) + (2y + 1) = 2x + 1 + 2y + 1 = 2x + 2y + 2 = 2(x + y + 1)).
If we add an odd number to an even number (same as adding an even number to an odd one), we always get an odd number ((2x + 1) + 2y = 2x + 1 + 2y = 2(x + y) + 1).
First of all, let's try to think about using an n which is not a prime, so maybe we will find out that these numbers are not good enough to be used as the length of a hash table (assuming that the keys share some patterns, e.g. like being all even or all odd).
Let's assume that n is even, i.e. n = 2y. In this case we have 2 scenarios: our keys k of K can be even (1.1.) or odd (1.2.).
1.1. n = 2y is even, keys are even k = 2x
For k = 2x and n = 2y, we have: k % n = 2x % 2y = i.
In this case we can say that if both the key k and hash table length n are even,
then i is also going to always be even.
Why? Because if we take the quotient by the integer division k // n = 2x // 2y = q, we get a quotient q such that:
k = 2x = (n * q) + i = (2y * q) + i = 2yq + i
Since 2yq (2y * q) is an even number, in order to satisfy 2x = 2yq + i the remainder i is always going to be even because 2x is even (even + even = even). If i were odd, we would get an odd number (even + odd = odd), but again 2x is even.
This leads to the following issue if we choose n to be even: if all our ks are even, then they will always end up in a bucket at an even index, increasing the number of collisions and clustering because only half n / 2 of the length of our hash table (only the even indices) will be occupied.
Therefore it's not a good idea to use an even number for n if all our ks or the majority of our ks are going to be even.
1.2. n = 2y is even, keys are odd k = 2x + 1
For k = 2x + 1 and n = 2y, we have: k % n = (2x + 1) % 2y = i.
Likewise, in this case if all of our ks (or the majority of them) are going to be odd, we end up in this situation:
k = 2x + 1 = (n * q) + i = (2y * q) + i = 2yq + i
Since 2yq is even, in order to get an odd k = 2x + 1, i is always going to be odd (even + odd = odd).
Again, choosing an even n as the hash table length is a bad idea even if all or the majority of our ks are odd, because we will end up with only the odd indices (buckets) being occupied.
So let's try with an n which is not an even number, i.e. an odd n = 2y + 1.
Let's assume that n is odd, i.e. n = 2y + 1. We still have even (2.1.) and odd (2.2.) keys (k of K).
2.1. n = 2y + 1 is odd, keys are even k = 2x
Here we have:
k = 2x = (n * q) + i = ((2y + 1) * q) + i = (2yq + q) + i = 2yq + q + i
We know that 2yq is even, so in order to get k = 2x which is even as well we need q + i to also be even.
When can q + i be even? Only in these 2 cases:
q -> even, i -> even, even + even = even
q -> odd, i -> odd, odd + odd = even
If either q or i is even while the other one is odd, we will get an odd q + i, and consequently an odd 2yq + (q + i), but we have k = 2x which is even, so either both q and i are even or they're both odd.
In this case we can see that for an odd n = 2y + 1, i can either be even or odd, which is good because it means that now we will use both even and odd bucket indices of our hash table and not only the even or only the odd ones.
By the way, it turns out that all primes p : p > 2 are odd numbers, so at least for now we can say that choosing a prime could be a good idea because a prime greater than 2 is always odd.
2.2. n = 2y + 1 is odd, keys are odd k = 2x + 1
Similarly here:
k = 2x + 1 = (n * q) + i = ((2y + 1) * q) + i = 2yq + q + i = 2yq + (q + i)
In order to get an odd k = 2x + 1 we need (q + i) to be odd (2yq is even), and this happens only in these 2 cases:
q -> even, i -> odd, even + odd = odd
q -> odd, i -> even, odd + even = odd
Again, we prove that an odd number is a better choice for n as this way we have the chance that both even and odd bucket's indices i are going to be occupied.
Now, I got stuck here. Is there a connection between this proof and prime numbers and how can I continue this proof to conclude that a prime number p would be an even better choice than a generic odd number with a similar reasoning?
EDIT:
So I tried to reason about it a bit further. This is what I came up with:
3. Using a generic odd n sharing a common factor f with k
We can say that for any factor f which is shared across k (k = f * x = fx) and n (n = f * y = fy), we end up with an i = k % n also sharing that common factor f. Why?
Again, if we try to compute k:
k = fx = (n * q) + i = (fy * q) + i = fyq + i
Then:
k = fx = fyq + i
Can only be satisfied if and only if i also shares f as one of its factors, e.g. i = f * g = fg:
k = fx = fyq + fg = f(yq + g)
Leading to yq + g = x.
This means that if both k and n share a common factor, then the result of the modulo i will also have that common factor and therefore i will always be a multiple of that common factor, e.g. for k of K = {12, 15, 33, 96, 165, 336} and n = 9 (an odd number, not a prime):
k | k % n
---------------------------
12 | 12 % 9 = 3
15 | 15 % 9 = 6
33 | 33 % 9 = 6
96 | 96 % 9 = 6
165 | 165 % 9 = 3
336 | 336 % 9 = 3
Both k and n always share a common factor (3 in this case).
This leads to i = k % n also being a multiple of 3 and therefore, again in such scenarios the hash table's bucket indices being used will only be those that are multiples of the common factor 3.
So while an odd number for n is definitely better than an even one (as explained at 2.1. and 2.2), we still may have unwanted patterns in numbers when k and n both share a common factor f.
So, if we make n a prime (n = p), we will certainly avoid that n shares that common factor f with k (provided that f != p), because a prime p can only have two factors: 1 and itself. So...
4. Using a prime for n
If n is a prime (n = p), we end up with:
k = fx = (q * p) + i = qp + i
Then:
k = fx = qp + i
Implies that the quotient q resulting from the integer division k // n can either share the common factor f or not, i.e.:
q = fz
Or:
q = z
In the first case (q = fz) we have:
k = fx = (q * p) + i = (fz * p) + i = fzp + i
So i ends up sharing the common factor f as well, e.g. i = fg:
k = fx = (q * p) + i = (fz * p) + i = fzp + i = fzp + fg = f(zp + g)
Such that zp + g = x.
And in the second case (q = z), we have:
k = fx = (q * p) + i = (z * p) + i = zp + i = zp + i
i.e. in this second case, i won't have f as one of its factors, as zp doesn't have f among its factors too.
So when using a prime for n, the benefit is that the result for i = k % n can either share a common factor f with k or not share it at all, e.g. for k of K = {56, 64, 72, 80, 88, 96} and n = p = 17:
k | k % n
---------------------------
56 | 56 % 17 = 5
64 | 64 % 17 = 13
72 | 72 % 17 = 4 ---> Common factor f = 4 of k and i
80 | 80 % 17 = 12 ---> Common factor f = 4 of k and i
88 | 88 % 17 = 3
96 | 96 % 17 = 11
In this case, all ks share a common factor f = 4, but only i = 72 % 17 = 4 and i = 80 % 17 = 12 both have k and i sharing that common factor f:
72 % 17 = 4 -> (18 * 4) % 17 = (4 * 1)
80 % 17 = 12 -> (20 * 4) % 17 = (4 * 3)
Also, if we take the previous example, for k of K = {12, 15, 33, 96, 165, 336} and we use the prime 17 for n instead of 9, we get:
k | k % n
---------------------------
12 | 12 % 17 = 12
15 | 15 % 17 = 15
33 | 33 % 17 = 16
96 | 96 % 17 = 11
165 | 165 % 17 = 12
336 | 336 % 17 = 13
Even here, we see that the common factor f = 3 in this case is shared between both k and n only in these 3 cases:
12 % 17 = 12 -> (4 * 3) % 17 = (4 * 3)
15 % 17 = 15 -> (5 * 3) % 17 = (5 * 3)
165 % 17 = 12 -> (55 * 3) % 17 = (4 * 3)
This way, using a prime, the probability for a collision has decreased, and we can distribute the data across the hash table better.
Now, what happens if even k is a prime, or at least a multiple of a prime? I think that in this case the distribution along the hash table would be even better, because there won't be any common factors between k and n if they are both primes or if k is a multiple of a prime, provided that k is not a multiple of the prime n.
This is my conclusion why a prime is better suited for the length of a hash table.
Would appreciate to receive your feedback and thoughts regarding my way of understanding this topic.
Thank you.
When it comes to chaining hash tables, you pretty much have the answer, although it can be written in fewer words:
Data often has patterns. Memory addresses, for example, often have zero in the lower bits.
Many hash functions, especially the very popular polynomial hash functions, are built using only addition, subtraction, and multiplication. All of these operations have the property that the lowest n bits of the result depend only on the lowest n bits of the operands, so these hash functions have this property too.
If your table size is zero in the lowest n bits, and the data is all the same in the lowest n bits, and your hash function has the property mentioned above... then your hash table will only use one out of every 2n of its slots.
Sometimes we fix this problem by choosing an odd hash table size. Prime sizes are better, because each small factor of the table size causes similar problems with different arithmetic progressions in hash values.
Sometimes, though, we fix this problem by adding an additional hash step to the hash table itself -- an additional hash step that mixes all the bits of the hash together and prevents this kinds of problems. Java HashMap uses tables with size 2N, but does this extra mixing step to help cover all the slots.
That's for chaining hash tables.
For hash tables that use open addressing to resolve collisions, the choice of a prime table size is usually required to ensure that the probing scheme will eventually check all (or at least half of) the slots. This is required to guarantee that the table will work at least until it is (half) full.
Related
Suppose I have given a number n. I want to find out all then even numbers which are less than n, and also have a greater exponent of 2 in its prime factorization than that of the exponent of 2 in the prime factorization of n.
if n=18 answer is 4 i.e, 4,8,12,16.
Using a for loop from i=2 to less than n and checking for every i will show time limit exceeded in the code.
My approach is to count no of times i will continue to divide by 2. But constraints of n=10^18. So, i think its a O (1) operation . Can anyone help me to find any formula or algorithm to find the answer as fast as possible?
First assume n is an odd number. Obviously every even number less than n also has a greater exponent of 2 in its factorization, so the answer will be equal to (n−1) / 2.
Now suppose n is equal to 2 times some odd number p. There are (p−1) / 2 even numbers that are smaller than p, so it follows that there are also (p−1) / 2 numbers smaller than n that are divisible by at least 22.
In general, given any number n that is equal to 2k times some odd number q, there will be (q−1) / 2 numbers that are smaller than n and have a larger exponent of 2 (> 2k) in their factorization.
So a function like this should work:
def count_smaller_numbers_with_greater_power_of_2_as_a_factor(n):
assert n > 0
while n % 2 == 0:
n >>= 1
return (n-1) // 2
Example 1 (n = 18)
Since n is even, keep dividing it by 2 until you get an odd number. This only takes one step (because n / 2 = 9)
Count the number of even numbers that are less than 9. This is equal to (9−1) / 2 = 4
Example 2 (n = 1018)
In this case, n = 218 × 518. So if we keep halving n until we get an odd number, the result will be 518.
The number of even numbers that are less than 518 is equal to (518−1) / 2 = 1907348632812
Your division is limited by constant number 64 (for 10^18~2^64), and O(64)=O(1) in complexity theory.
Number of two's in value factorization is equal to the number of trailing zero bits in binary representation of this value, so you can use bit operations (like & 1 and right shift shr, >>) to accelerate code a bit or apply some bit tricks
First, suppose n = 2^k * something. Find out k:
long k = 0;
while(n % 2 == 0) { n >>= 1; k++; }
n <<= k;
Now that you know who is k, multiply 2^k by 2 to get the first power of 2 greater than 2^k:
long next_power = 1 << (k + 1); // same as 2^(k + 1)
And lastly, check if n is odd. If it isn't, print all the multiples of next_power:
if(k == 0){ //equivalent to testing n % 2 == 0
for(long i = next_power; i < n; i += next_power) cout<<i<<endl;
}
EXAMPLE: n = 18
k will be 1, because 18 = 2^1 * 9 and the while will finish there.
next_power will be 4 (= 1 << (k + 1) = 2 ^ (k + 1)).
for(long i = next_power; i < n; i += next_power) cout<<i<<endl; will print 4, 8, 12 and 16.
This is very easy to do with a gcd trick i found:
You can find the count by //4. So 10^18 has
In [298]: pow(10,18)//4
Out[298]: 250000000000000000
You can find the count of 18 by //4 which is 4
Fan any numbers that meet your criteria. You can check by using my
algorithm here, and taking the len of the array and conpare with the
number div//4 to see that that is the answer your looking for: an exact
match. You'll notice that it's every four numbers that don't have an
exponent of 2. So the count of numbers can be found with //4.
import math
def lars_last_modulus_powers_of_two(hm):
return math.gcd(hm, 1<<hm.bit_length())
def findevennumberswithexponentgreaterthan2lessthannum(hm):
if hm %2 != 0:
return "only for use of even numbers"
vv = []
for x in range(hm,1,-2):
if lars_last_modulus_powers_of_two(x) != 2:
vv.append(x)
return vv
Result:
In [3132]: findevennumberswithexponentgreaterthan2lessthannum(18)
Out[3132]: [16, 12, 8, 4]
This is the fastest way to do it as you skip the mod down the path to get the answer. Instantly get the number you need with lars_last_modulus_powers_of_two(num) which is one operation per number.
Here is some example to show the answer is right:
In [302]: len(findevennumberswithexponentgreaterthan2lessthannum(100))
Out[302]: 25
In [303]: 100//4
Out[303]: 25
In [304]: len(findevennumberswithexponentgreaterthan2lessthannum(1000))
Out[304]: 250
In [305]: 1000//4
Out[305]: 250
In [306]: len(findevennumberswithexponentgreaterthan2lessthannum(23424))
Out[306]: 5856
In [307]: 23424//4
Out[307]: 5856
is there an algorithm that find all binaries numbers between a and b, in which there are exactly two one?
For example:
a = 5
b = 10
find(a, b)
It will find
5 = 00000101
6 = 00000110
9 = 00001001
10 = 00001010
A bit-hacking trick that iterates through all bit-paterns that contain the same number of 1-bits looks as follows
unsigned next_combination(unsigned x)
{
unsigned u = x & -x;
unsigned v = u + x;
x = v + (((v ^ x) / u) >> 2);
return x;
}
It generates the values in ascending order. It takes the previous value and transforms it into the next one with the same number of 1-bits. This means that you just have to start from the minimal bit combination that is greater or equal to a and iterate until you encounter a value greater than b.
Of course, in this form it will only work if your a and b are within the range of unsigned.
These numbers are of the form
2^m + 2^n
with m > n.
You can find them by exhaustive search on m, n.
M= 1
while M < b:
N= 1
while M + N <= b:
if a <= M + N:
print M + N
N+= N
M+= M
This can probably slightly be optimized to avoid searching when 2^m < a, but the benefit will be tiny: the complexity is O(log²b), which is already small.
Here is an interesting programming puzzle I came across . Given an array of positive integers, and a number K. We need to find pairs(a,b) from the array such that a % b = K.
I have a naive O(n^2) solution to this where we can check for all pairs such that a%b=k. Works but inefficient. We can certainly do better than this can't we ? Any efficient algorithms for the same? Oh and it's NOT homework.
Sort your array and binary search or keep a hash table with the count of each value in your array.
For a number x, we can find the largest y such that x mod y = K as y = x - K. Binary search for this y or look it up in your hash and increment your count accordingly.
Now, this isn't necessarily the only value that will work. For example, 8 mod 6 = 8 mod 3 = 2. We have:
x mod y = K => x = q*y + K =>
=> x = q(x - K) + K =>
=> x = 1(x - K) + K =>
=> x = 2(x - K)/2 + K =>
=> ...
This means you will have to test all divisors of y as well. You can find the divisors in O(sqrt y), giving you a total complexity of O(n log n sqrt(max_value)) if using binary search and O(n sqrt(max_value)) with a hash table (recommended especially if your numbers aren't very large).
Treat the problem as having two separate arrays as input: one for the a numbers and a % b = K and one for the b numbers. I am going to assume that everything is >= 0.
First of all, you can discard any b <= K.
Now think of every number in b as generating a sequence K, K + b, K + 2b, K + 3b... You can record this using a pair of numbers (pos, b), where pos is incremented by b at each stage. Start with pos = 0.
Hold these sequences in a priority queue, so you can find the smallest pos value at any given time. Sort the array of a numbers - in fact you could do this ahead of time and discard any duplicates.
For each a number
While the smallest pos in the priority queue is <= a
Add the smallest multiple of b to it to make it >= a
If it is == a, you have a match
Update the stored value of pos for that sequence, re-ordering the priority queue
At worst, you end up comparing every number with every other number, which is the same as the simple solution, but with priority queue and sorting overhead. However, large values of b may remain unexamined in the priority queue while several a numbers pass through, in which case this does better - and if there are a lot of numbers to process and they are all different, some of them must be large.
This answer mentions the main points of an algorithm (called DL because it uses “divisor lists” ) and gives details via a program, called amodb.py.
Let B be the input array, containing N positive integers. Without much loss of generality, suppose B[i] > K for all i and that B is in ascending order. (Note that x%B[i] < K if B[i] < K; and where B[i] = K, one can report pairs (B[i], B[j]) for all j>i. If B is not sorted initially, charge a cost of O(N log N) to sort it.)
In algorithm DL and program amodb.py, A is an array with K pre-subtracted from the input array elements. Ie, A[i] = B[i] - K. Note that if a%b == K, then for some j we have a = b*j + K or a-K = b*j. That is, a%b == K iff a-K is a multiple of b. Moreover, if a-K = b*j and p is any factor of b, then p is a factor of a-K.
Let the prime numbers from 2 to 97 be called “small factors”. When N numbers are uniformly randomly selected from some interval [X,Y], on the order of N/ln(Y) of the numbers will have no small factors; a similar number will have a greatest small factor of 2; and declining proportions will have successively larger greatest small factors. For example, on the average about N/97 will be divisible by 97, about N/89-N/(89*97) by 89 but not 97, etc. Generally, when members of B are random, lists of members with certain greatest small factors or with no small factors are sub-O(N/ln(Y)) in length.
Given a list Bd containing members of B divisible by largest small factor p, DL tests each element of Bd against elements of list Ad, those elements of A divisible by p. But given a list Bp for elements of B without small factors, DL tests each of Bp's elements against all elements of A. Example: If N=25, p=13, Bd=[18967, 23231], and Ad=[12779, 162383], then DL tests if any of 12779%18967, 162383%18967, 12779%23231, 162383%23231 are zero. Note that it is possible to cut the number of tests in half in this example (and many others) by noticing 12779<18967, but amodb.py does not include that optimization.
DL makes J different lists for J different factors; in one version of amodb.py, J=25 and the factor set is primes less than 100. A larger value of J would increase the O(N*J) time to initialize divisor lists, but would slightly decrease the O(N*len(Bp)) time to process list Bp against elements of A. See results below. Time to process other lists is O((N/logY)*(N/logY)*J), which is in sharp contrast to the O(n*sqrt(Y)) complexity for a previous answer's method.
Shown next is output from two program runs. In each set, the first Found line is from a naïve O(N*N) test, and the second is from DL. (Note, both DL and the naïve method would run faster if too-small A values were progressively removed.) The time ratio in the last line of the first test shows a disappointingly low speedup ratio of 3.9 for DL vs naïve method. For that run, factors included only the 25 primes less than 100. For the second run, with better speedup of ~ 4.4, factors included numbers 2 through 13 and primes up to 100.
$ python amodb.py
N: 10000 K: 59685 X: 100000 Y: 1000000
Found 208 matches in 21.854 seconds
Found 208 matches in 5.598 seconds
21.854 / 5.598 = 3.904
$ python amodb.py
N: 10000 K: 97881 X: 100000 Y: 1000000
Found 207 matches in 21.234 seconds
Found 207 matches in 4.851 seconds
21.234 / 4.851 = 4.377
Program amodb.py:
import random, time
factors = [2,3,4,5,6,7,8,9,10,11,12,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
X, N = 100000, 10000
Y, K = 10*X, random.randint(X/2,X)
print "N: ", N, " K: ", K, "X: ", X, " Y: ", Y
B = sorted([random.randint(X,Y) for i in range(N)])
NP = len(factors); NP1 = NP+1
A, Az, Bz = [], [[] for i in range(NP1)], [[] for i in range(NP1)]
t0 = time.time()
for b in B:
a, aj, bj = b-K, -1, -1
A.append(a) # Add a to A
for j,p in enumerate(factors):
if a % p == 0:
aj = j
Az[aj].append(a)
if b % p == 0:
bj = j
Bz[bj].append(b)
Bp = Bz.pop() # Get not-factored B-values list into Bp
di = time.time() - t0; t0 = time.time()
c = 0
for a in A:
for b in B:
if a%b == 0:
c += 1
dq = round(time.time() - t0, 3); t0 = time.time()
c=0
for i,Bd in enumerate(Bz):
Ad = Az[i]
for b in Bd:
for ak in Ad:
if ak % b == 0:
c += 1
for b in Bp:
for ak in A:
if ak % b == 0:
c += 1
dr = round(di + time.time() - t0, 3)
print "Found", c, " matches in", dq, "seconds"
print "Found", c, " matches in", dr, "seconds"
print dq, "/", dr, "=", round(dq/dr, 3)
Source: Facebook Hacker Cup Qualification Round 2011
A double-square number is an integer X which can be expressed as the sum of two perfect squares. For example, 10 is a double-square because 10 = 32 + 12. Given X, how can we determine the number of ways in which it can be written as the sum of two squares? For example, 10 can only be written as 32 + 12 (we don't count 12 + 32 as being different). On the other hand, 25 can be written as 52 + 02 or as 42 + 32.
You need to solve this problem for 0 ≤ X ≤ 2,147,483,647.
Examples:
10 => 1
25 => 2
3 => 0
0 => 1
1 => 1
Factor the number n, and check if it has a prime factor p with odd valuation, such that p = 3 (mod 4). It does if and only if n is not a sum of two squares.
The number of solutions has a closed form expression involving the number of divisors of n. See this, Theorem 3 for a precise statement.
Here is my simple answer in O(sqrt(n)) complexity
x^2 + y^2 = n
x^2 = n-y^2
x = sqrt(n - y^2)
x should be integer so (n-y^2) should be perfect square. Loop to y=[0, sqrt(n)] and check whether (n-y^2) is perfect square or not
Pseudocode :
count = 0;
for y in range(0, sqrt(n))
if( isPerfectSquare(n - y^2))
count++
return count/2
Here's a much simpler solution:
create list of squares in the given range (that's 46340 values for the example given)
for each square value x
if list contains a value y such that x + y = target value (i.e. does [target - x] exist in list)
output √x, √y as solution (roots can be stored in a std::map lookup created in the first step)
Looping through all pairs (a, b) is infeasible given the constrains on X. There is a faster way though!
For fixed a, we can work out b: b = √(X - a2). b won't always be an integer though, so we have to check this. Due to precision issues, perform the check with a small tolerance: if b is x.99999, we can be fairly certain it's an integer. So we loop through all possible values of a and count all cases where b is an integer. We need to be careful not to double-count, so we place the constraint that a <= b. For X = a2 + b2, a will be at most √(X/2) with this constraint.
Here is an implementation of this algorithm in C++:
int count = 0;
// add EPS to avoid flooring x.99999 to x
for (int a = 0; a <= sqrt(X/2) + EPS; a++) {
int b2 = X - a*a; // b^2
int b = (int) (sqrt(b2) + EPS);
if (abs(b - sqrt(b2)) < EPS) // check b is an integer
count++;
}
cout << count << endl;
See it on ideone with sample input
Here's a version which is trivially O(sqrt(N)) and avoids all loop-internal branches.
Start by generating all squares up to the limit, easily done without any multiplications, then initialize a l and r index.
In each iteration you calculate the sum, then update the two indices and the count based on a comparison with the target value. This is sqrt(N) iterations to generate the table and maximum sqrt(N) iterations of the search loop. Estimated running time with a reasonable compiler is max 10 clock cycles per sqrt(N), so for a maximum input value if 2^31 (sqrt(N) ~= 46341) this should correspond to less than 500K clock cycles or a few tenths of a second:
unsigned countPairs(unsigned n)
{
unsigned sq = 0, i;
unsigned square[65536];
for (i = 0; sq <= n; i++) {
square[i] = sq;
sq += i+i+1;
}
unsigned l = 0, r = i-1, count = 0;
do {
unsigned sum = square[l] + square[r];
l += sum <= n; // Increment l if the sum is <= N
count += sum == n; // Increment the count if a match
r -= sum >= n; // Decrement r if the sum is >= N
} while (l <= r);
return count;
}
A good compiler can note that the three compares at the end are all using the same operands so it only needs a single CMP opcode followed by three different conditional move operations (CMOVcc).
I was in a hurry, so solved it using a rather brute-force approach (very similar to marcog's) using Python 2.6.
def is_perfect_square(x):
rt = int(math.sqrt(x))
return rt*rt == x
def double_sqaures(n):
rng = int(math.sqrt(n))
ways = 0
for i in xrange(rng+1):
if is_perfect_square(n - i*i):
ways +=1
if ways % 2 == 0:
ways = ways // 2
else:
ways = ways // 2 + 1
return ways
Note: ways will be odd when the number is a perfect sqaure.
The number of solutions (x,y) of
x^2+y^2=n
over the integers is exactly 4 times the number of divisors of n congruent to 1 mod 4.
Similar identities exist also for the problems
x^2 + 2y^2 = n
and
x^2 + y^2 + z^2 + w^2 = n.
I would like to calculate:
abcd... mod m
Do you know any efficient way since this number is too big but a , b , c , ... and m fit in a simple 32-bit int.
Any Ideas?
Caveat: This question is different from finding ab mod m.
Also please note that abc is not the same as (ab)c. The later is equal to abc. Exponentiation is right-associative.
abc mod m = abc mod n mod m, where n = φ(m) Euler's totient function.
If m is prime, then n = m-1.
Edit: as Nabb pointed out, this only holds if a is coprime to m. So you would have to check this first.
The answer does not contain full formal mathematical proof of correctness. I assumed that it is unnecessary here. Besides, it would be very illegible on SO, (no MathJax for example).
I will use (just a little bit) specific prime factorization algorithm. It's not best option, but enough.
tl;dr
We want calculate a^x mod m. We will use function modpow(a,x,m). Described below.
If x is small enough (not exponential form or exists p^x | m) just calculate it and return
Split into primes and calculate p^x mod m separately for each prime, using modpow function
Calculate c' = gcd(p^x,m) and t' = totient(m/c')
Calculate w = modpow(x.base, x.exponent, t') + t'
Save pow(p, w - log_p c', m) * c' in A table
Multiple all elements from A and return modulo m
Here pow should look like python's pow.
Main problem:
Because current best answer is about only special case gcd(a,m) = 1, and OP did not consider this assumption in question, I decided to write this answer. I will also use Euler's totient theorem. Quoting wikipedia:
Euler's totient theorem:
If n and a are coprime positive integers, then
where φ(n) is Euler's totient function.
The assumption numbers are co-primeis very important, as Nabb shows in comment. So, firstly we need to ensure that the numbers are co-prime. (For greater clarity assume x = b^(c^...).) Because , where we can factorize a, and separately calculate q1 = (p1^alpha)^x mod m,q2 = (p2^beta)^x mod m... and then calculate answer in easy way (q1 * q2 * q3 * ... mod m). Number has at most o(log a) prime factors, so we will be force to perform at most o(log a) calculations.
In fact we doesn't have to split to every prime factor of a (if not all occur in m with other exponents) and we can combine with same exponent, but it is not noteworthy by now.
Now take a look at (p^z)^x mod m problem, where p is prime. Notice some important observation:
If a,b are positive integers smaller than m and c is some positive integer and , then true is sentence .
Using the above observation, we can receive solution for actual problem. We can easily calculate gcd((p^z)^x, m). If x*z are big, it is number how many times we can divide m by p. Let m' = m /gcd((p^z)^x, m). (Notice (p^z)^x = p^(z*x).) Let c = gcd(p^(zx),m). Now we can easily (look below) calculate w = p^(zx - c) mod m' using Euler's theorem, because this numbers are co-prime! And after, using above observation, we can receive p^(zx) mod m. From above assumption wc mod m'c = p^(zx) mod m, so the answer for now is p^(zx) mod m = wc and w,c are easy to calculate.
Therefore we can easily calculate a^x mod m.
Calculate a^x mod m using Euler's theorem
Now assume a,m are co-prime. If we want calculate a^x mod m, we can calculate t = totient(m) and notice a^x mod m = a^(x mod t) mod m. It can be helpful, if x is big and we know only specific expression of x, like for example x = 7^200.
Look at example x = b^c. we can calculate t = totient(m) and x' = b^c mod t using exponentiation by squaring algorithm in Θ(log c) time. And after (using same algorithm) a^x' mod m, which is equal to solution.
If x = b^(c^(d^...) we will solve it recursively. Firstly calculate t1 = totient(m), after t2 = totient(t1) and so on. For example take x=b^(c^d). If t1=totient(m), a^x mod m = a^(b^(c^d) mod t1), and we are able to say b^(c^d) mod t1 = b^(c^d mod t2) mod t1, where t2 = totient(t1). everything we are calculating using exponentiation by squaring algorithm.
Note: If some totient isn't co-prime to exponent, it is necessary to use same trick, as in main problem (in fact, we should forget that it's exponent and recursively solve problem, like in main problem). In above example, if t2 isn't relatively prime with c, we have to use this trick.
Calculate φ(n)
Notice simple facts:
if gcd(a,b)=1, then φ(ab) = φ(a)*φ(b)
if p is prime φ(p^k)=(p-1)*p^(k-1)
Therefore we can factorize n (ak. n = p1^k1 * p2^k2 * ...) and separately calculate φ(p1^k1),φ(p2^k2),... using fact 2. Then combine this using fact 1. φ(n)=φ(p1^k1)*φ(p2^k2)*...
It is worth remembering that, if we will calculate totient repeatedly, we may want to use Sieve of Eratosthenes and save prime numbers in table. It will reduce the constant.
python example: (it is correct, for the same reason as this factorization algorithm)
def totient(n) : # n - unsigned int
result = 1
p = 2 #prime numbers - 'iterator'
while p**2 <= n :
if(n%p == 0) : # * (p-1)
result *= (p-1)
n /= p
while(n%p == 0) : # * p^(k-1)
result *= p
n /= p
p += 1
if n != 1 :
result *= (n-1)
return result # in O(sqrt(n))
Case: abc mod m
Cause it's in fact doing the same thing many times, I believe this case will show you how to solve this generally.
Firstly, we have to split a into prime powers. Best representation will be pair <number,
exponent>.
c++11 example:
std::vector<std::tuple<unsigned, unsigned>> split(unsigned n) {
std::vector<std::tuple<unsigned, unsigned>> result;
for(unsigned p = 2; p*p <= n; ++p) {
unsigned current = 0;
while(n % p == 0) {
current += 1;
n /= p;
}
if(current != 0)
result.emplace_back(p, current);
}
if(n != 1)
result.emplace_back(n, 1);
return result;
}
After split, we have to calculate (p^z)^(b^c) mod m=p^(z*(b^c)) mod m for every pair. Firstly we should check, if p^(z*(b^c)) | m. If, yes the answer is just (p^z)^(b^c), but it's possible only in case in which z,b,c are very small. I believe I don't have to show code example to it.
And finally if p^(z*b^c) > m we have to calculate the answer. Firstly, we have to calculate c' = gcd(m, p^(z*b^c)). After we are able to calculate t = totient(m'). and (z*b^c - c' mod t). It's easy way to get an answer.
function modpow(p, z, b, c, m : integers) # (p^z)^(b^c) mod m
c' = 0
m' = m
while m' % p == 0 :
c' += 1
m' /= p
# now m' = m / gcd((p^z)^(b^c), m)
t = totient(m')
exponent = z*(b^c)-c' mod t
return p^c' * (p^exponent mod m')
And below Python working example:
def modpow(p, z, b, c, m) : # (p^z)^(b^c) mod m
cp = 0
while m % p == 0 :
cp += 1
m /= p # m = m' now
t = totient(m)
exponent = ((pow(b,c,t)*z)%t + t - (cp%t))%t
# exponent = z*(b^c)-cp mod t
return pow(p, cp)*pow(p, exponent, m)
Using this function, we can easily calculate (p^z)^(b^c) mod m, after we just have to multiple all results (mod m), we can also calculate everything on an ongoing basis. Example below. (I hope I didn't make mistake, writing.) Only assumption, b,c are big enough (b^c > log(m) ak. each p^(z*b^k) doesn't divide m), it's simple check and I don't see point to make clutter by it.
def solve(a,b,c,m) : # split and solve
result = 1
p = 2 # primes
while p**2 <= a :
z = 0
while a % p == 0 :
# calculate z
a /= p
z += 1
if z != 0 :
result *= modpow(p,z,b,c,m)
result %= m
p += 1
if a != 1 : # Possible last prime
result *= modpow(a, 1, b, c, m)
return result % m
Looks, like it works.
DEMO and it's correct!
Since for any relationship a=x^y, the relationship is invariant with respect to the numeric base you are using (base 2, base 6, base 16, etc).
Since the mod N operation is equivalent to extracting the least significant digit (LSD) in base N
Since the LSD of the result A in base N can only be affected by the LSD of X in base N, and not digits in higher places. (e.g. 34*56 = 30*50+30*6+50*4+4*5 = 10*(3+50+3*6+5*4)+4*6)
Therefore, from LSD(A)=LSD(X^Y) we can deduce
LSD(A)=LSD(LSD(X)^Y)
Therefore
A mod N = ((X mod N) ^ Y) mod N
and
(X ^ Y) mod N = ((X mod N) ^ Y) mod N)
Therefore you can do the mod before each power step, which keeps your result in the range of integers.
This assumes a is not negative, and for any x^y, a^y < MAXINT
This answer answers the wrong question. (alex)
Modular Exponentiation is a correct way to solve this problem, here's a little bit of hint:
To find abcd % m
You have to start with calculating
a % m, then ab % m, then abc % m and then abcd % m ... (you get the idea)
To find ab % m, you basically need two ideas: [Let B=floor(b/2)]
ab = (aB)2 if b is even OR ab = (aB)2*a if b is odd.
(X*Y)%m = ((X%m) * (Y%m)) % m
(% = mod)
Therefore,
if b is even
ab % m = (aB % m)2 % m
or if b is odd
ab % m = (((aB % m)2) * (a % m)) % m
So if you knew the value of aB, you can calculate this value.
To find aB, apply similar approach, dividing B until you reach 1.
e.g. To calculate 1613 % 11:
1613 % 11 = (16 % 11)13 % 11 = 513 % 11
= (56 % 11) * (56 % 11) * (5 % 11) <---- (I)
To find 56 % 11:
56 % 11 = ((53 % 11) * (53 % 11)) % 11 <----(II)
To find 53%11:
53 % 11 = ((51 % 11) * (51 % 11) * (5 % 11)) % 11
= (((5 * 5) % 11) * 5) % 11 = ((25 % 11) * 5) % 11 = (3 * 5) % 11 = 15 % 11 = 4
Plugging this value to (II) gives
56 % 11 = (((4 * 4) % 11) * 5) % 11 = ((16 % 11) * 5) % 11 = (5 * 5) % 11 = 25 % 11 = 3
Plugging this value to (I) gives
513 % 11 = ((3 % 11) * (3 % 11) * 5) % 11 = ((9 % 11) * 5) % 11 = 45 % 11 = 4
This way 513 % 11 = 4
With this you can calculate anything of form a513 % 11 and so on...
Look at the behavior of A^X mod M as X increases. It must eventually go into a cycle. Suppose the cycle has length P and starts after N steps. Then X >= N implies A^X = A^(X+P) = A^(X%P + (-N)%P + N) (mod M). Therefore we can compute A^B^C by computing y=B^C, z = y < N ? y : y%P + (-N)%P + N, return A^z (mod m).
Notice that we can recursively apply this strategy up the power tree, because the derived equation either has an exponent < M or an exponent involving a smaller exponent tower with a smaller dividend.
The only question is if you can efficiently compute N and P given A and M. Notice that overestimating N is fine. We can just set N to M and things will work out. P is a bit harder. If A and M are different primes, then P=M-1. If A has all of M's prime factors, then we get stuck at 0 and P=1. I'll leave it as an exercise to figure that out, because I don't know how.
///Returns equivalent to list.reverse().aggregate(1, acc,item => item^acc) % M
func PowerTowerMod(Link<int> list, int M, int upperB = M)
requires M > 0, upperB >= M
var X = list.Item
if list.Next == null: return X
var P = GetPeriodSomehow(base: X, mod: M)
var e = PowerTowerMod(list.Next, P, M)
if e^X < upperB then return e^X //todo: rewrite e^X < upperB so it doesn't blowup for large x
return ModPow(X, M + (e-M) % P, M)
Tacet's answer is good, but there are substantial simplifications possible.
The powers of x, mod m, are preperiodic. If x is relatively prime to m, the powers of x are periodic, but even without that assumption, the part before the period is not long, at most the maximum of the exponents in the prime factorization of m, which is at most log_2 m. The length of the period divides phi(m), and in fact lambda(m), where lambda is Carmichael's function, the maximum multiplicative order mod m. This can be significantly smaller than phi(m). Lambda(m) can be computed quickly from the prime factorization of m, just as phi(m) can. Lambda(m) is the GCD of lambda(p_i^e_i) over all prime powers p_i^e_i in the prime factorization of m, and for odd prime powers, lambda(p_i^e_i) = phi(p_i^e^i). lambda(2)=1, lamnda(4)=2, lambda(2^n)=2^(n-2) for larger powers of 2.
Define modPos(a,n) to be the representative of the congruence class of a in {0,1,..,n-1}. For nonnegative a, this is just a%n. For a negative, for some reason a%n is defined to be negative, so modPos(a,n) is (a%n)+n.
Define modMin(a,n,min) to be the least positive integer congruent to a mod n that is at least min. For a positive, you can compute this as min+modPos(a-min,n).
If b^c^... is smaller than log_2 m (and we can check whether this inequality holds by recursively taking logarithms), then we can simply compute a^b^c^... Otherwise, a^b^c^... mod m = a^modMin(b^c^..., lambda(m), [log_2 m])) mod m = a^modMin(b^c^... mod lambda(m), lambda(m),[log_2 m]).
For example, suppose we want to compute 2^3^4^5 mod 100. Note that 3^4^5 only has 489 digits, so this is doable by other methods, but it's big enough that you don't want to compute it directly. However, by the methods I gave here, you can compute 2^3^4^5 mod 100 by hand.
Since 3^4^5 > log_2 100,
2^3^4^5 mod 100
= 2^modMin(3^4^5,lambda(100),6) mod 100
= 2^modMin(3^4^5 mod lambda(100), lambda(100),6) mod 100
= 2^modMin(3^4^5 mod 20, 20,6) mod 100.
Let's compute 3^4^5 mod 20. Since 4^5 > log_2 20,
3^4^5 mod 20
= 3^modMin(4^5,lambda(20),4) mod 20
= 3^modMin(4^5 mod lambda(20),lambda(20),4) mod 20
= 3^modMin(4^5 mod 4, 4, 4) mod 20
= 3^modMin(0,4,4) mod 20
= 3^4 mod 20
= 81 mod 20
= 1
We can plug this into the previous calculation:
2^3^4^5 mod 100
= 2^modMin(3^4^5 mod 20, 20,6) mod 100
= 2^modMin(1,20,6) mod 100
= 2^21 mod 100
= 2097152 mod 100
= 52.
Note that 2^(3^4^5 mod 20) mod 100 = 2^1 mod 100 = 2, which is not correct. You can't reduce down to the preperiodic part of the powers of the base.