Given two integers is there an easy way to find the largest modulus of congruence for them? i.e. a % n == b %n, Or even to enumerate all of them? Obviously, I could try every value less than them, but it seems like there should be an easier way.
I tried doing something with gcds, but then you just get things where a % n == b % n == 0, which isn't as cool as I was hoping for, and I'm pretty sure this isn't necessarily the largest n.
Any ideas?
If a and b are the numbers, then we consider:
a = nx + r
b = ny + r
Where n is the modulus we want to find, and r is the common remainder. So,
a - b = n(x - y)
Maximum n is achieved with x - y = 1. So,
n = a - b
(If I understood the question correctly.)
Related
Problem : 5 monkeys, 5 snakes and 5 tigers are standing in a line in a grocery store, with animals of the same species being indistinguishable. A monkey stands in the front of the line, and a tiger stands at the end of the line. Unfortunately, tigers and monkeys are sworn enemies, so monkeys and tigers cannot stand in adjacent places in line. Compute the number of possible arrangements of the line.
Solving this problem by hand is daunting. I want to write a program to output the possible arrangements and also count the total arrangements. My first thought was to use a brute force. Monkeys, snakes, and tigers can be represented by the letters M, S, and T respectively. With 1 M at start of string and 1 T at the end, there are 13!/(4!4!5!) = 90,090 possibilities. I would then remove arrangements that do not satisfy the second condition about adjacency.
My second thought was to first compute the number of arrangements where M and T are adjacent and then subtract this number from 90,090. I am new to programming so I am not sure how to do this.
Is there a better way to approach these types of problems? Any hints?
Thank you.
TL;DR: python solution using sympy
import sympy # sympy.ntheory.multinomial_coefficients
import math # math.comb
def count_monkeytigers(n_monkeys, n_snakes, n_tigers):
return sum(
m * math.comb(n_monkeys - 1, mb_minus1) * math.comb(n_tigers - 1, tb_minus1)
for (mb_minus1, eb, tb_minus1), m in
sympy.ntheory.multinomial_coefficients(3, n_snakes-1).items()
)
Explanation
We already know that there is an M at the beginning, a T at the end, and five S in the string:
M?? S ?? S ?? S ?? S ?? S ??T
Since M and T cannot be adjacent, and the only way to separate them is with an S, you can think of the S as separators; the five S are cutting the string into 6 "bins". Every bin can either be empty, or contain one or more M, or contain one or more T. Furthermore, the first bin contains at least an M, and the last bin contains at least a T.
To count all permutations of the string, we can do the following:
Loop over the triplets (monkey_bins, empty_bins, tiger_bins) deciding how many bins have monkeys, are empty, or have tigers;
For the loop, we can use bounds 1 <= monkey_bins <= 5; 0 <= empty_bins <= 5 - monkey_bins; tiger_bins = 6 - monkey_bins - empty_bins;
Count the number m of ways to choose monkey_bins bins, empty_bins bins and tiger_bins bins among 6 bins (Multinomial coefficient);
Count the number monkey_partitions of ways to place n_monkeys 'M' into monkey_bins bins with at least one M per bin (Stars and bars theorem 1);
Count the number tiger_partitions of ways to place n_tigers 'T' into tiger_bins bins with at least one T per bin (Stars and bars theorem 1;
Add m * monkey_partitions * tiger_partitions to the count.
Python code with loops
import math
def multinomial(*params):
return math.prod(math.comb(sum(params[:i]), x) for i, x in enumerate(params, 1))
def count_monkeytigers(n_monkeys, n_snakes, n_tigers):
result = 0
for monkey_bins in range(1, n_snakes + 1):
for empty_bins in range(0, n_snakes + 1 - monkey_bins):
tiger_bins = n_snakes + 1 - monkey_bins - empty_bins
m = multinomial(monkey_bins - 1, empty_bins, tiger_bins - 1) # nb permutations of the 3 types of bins
monkey_partitions = math.comb(n_monkeys - 1, monkey_bins - 1)
tiger_partitions = math.comb(n_tigers - 1, tiger_bins - 1)
result += m * monkey_partitions * tiger_partitions
return result
print(count_monkeytigers(5, 5, 5))
# 1251
print(count_monkeytigers(2,2,2))
# 3
# = len(['MMSSTT', 'MSMSTT', 'MMSTST'])
The code for multinomial comes from this question:
Does python have a function which computes multinomial coefficients?
Note that we're only using a "trinomial" coefficient here, so you can replace function multinomial with this simpler function if you want:
def trinomial(k1,k2,k3):
return math.comb(k1+k2+k3, k1) * math.comb(k2+k3, k2)
Python code using sympy
In the previous python code, we're manually looping over the possible triplets (monkey_bins, empty_bins, tiger_bins) and using the corresponding binomial coefficients. As it turns out, sympy.ntheory.multinomial_coefficients(m, n) returns a dictionary that contains specifically those triplets as keys and the corresponding multinomial coefficients as values!
We can use that to shorten our code:
import sympy # sympy.ntheory.multinomial_coefficients
import math # math.comb
def count_monkeytigers(n_monkeys, n_snakes, n_tigers):
return sum(
m * math.comb(n_monkeys - 1, mb_minus1) * math.comb(n_tigers - 1, tb_minus1)
for (mb_minus1, eb, tb_minus1), m in
sympy.ntheory.multinomial_coefficients(3, n_snakes-1).items()
)
print(count_monkeytigers(5, 5, 5))
# 1251
print(count_monkeytigers(2,2,2))
# 3
# = len(['MMSSTT', 'MSMSTT', 'MMSTST'])
Note that the dictionary multinomial_coefficients(3, n) contains all triplets of nonnegative numbers summing to n, including those where the middle-element empty_bins is equal to n, and the other two elements are 0. But we want at least one bin with monkeys, and at least one bin with tigers; hence I called the triplet (mb_minus1, eb, tb_minus1) rather than (mb, eb, tb), and accordingly I used n_snakes-1 rather than n_snakes+1 as the sum of the triplet.
Before writing code directly , Just solve the question on paper upto the factorial notations , then you can easily find factorial in Code
At first , fix 1 monkey at front and 1 tiger at end .
Then try to fix remaining tigers , then fix snakes in adjancent of tigers , Atleast one snake must be in adjacent of a tiger and then fix monkeys in adjacent of snakes
Let's assume I have an N-bit stream of generated bits. (In my case 64kilobits.)
Whats the probability of finding a sequence of X "all true" bits, contained within a stream of N bits. Where X = (2 to 16), and N = (16 to 1000000), and X < N.
For example:
If N=16 and X=5, whats the likelyhood of finding 11111 within a 16-bit number.
Like this pseudo-code:
int N = 1<<16; // (64KB)
int X = 5;
int Count = 0;
for (int i = 0; i < N; i++) {
int ThisCount = ContiguousBitsDiscovered(i, X);
Count += ThisCount;
}
return Count;
That is, if we ran an integer in a loop from 0 to 64K-1... how many times would 11111 appear within those numbers.
Extra rule: 1111110000000000 doesn't count, because it has 6 true values in a row, not 5. So:
1111110000000000 = 0x // because its 6 contiguous true bits, not 5.
1111100000000000 = 1x
0111110000000000 = 1x
0011111000000000 = 1x
1111101111100000 = 2x
I'm trying to do some work involving physically-based random-number generation, and detecting "how random" the numbers are. Thats what this is for.
...
This would be easy to solve if N were less than 32 or so, I could just "run a loop" from 0 to 4GB, then count how many contiguous bits were detected once the loop was completed. Then I could store the number and use it later.
Considering that X ranges from 2 to 16, I'd literally only need to store 15 numbers, each less than 32 bits! (if N=32)!
BUT in my case N = 65,536. So I'd need to run a loop, for 2^65,536 iterations. Basically impossible :)
No way to "experimentally calculate the values for a given X, if N = 65,536". So I need maths, basically.
Fix X and N, obiously with X < N. You have 2^N possible values of combinations of 0 and 1 in your bit number, and you have N-X +1 possible sequences of 1*X (in this part I'm only looking for 1's together) contained in you bit number. Consider for example N = 5 and X = 2, this is a possible valid bit number 01011, so fixed the last two characteres (the last two 1's) you have 2^2 possible combinations for that 1*Xsequence. Then you have two cases:
Border case: Your 1*X is in the border, then you have (2^(N -X -1))*2 possible combinations
Inner case: You have (2^(N -X -2))*(N-X-1) possible combinations.
So, the probability is (border + inner )/2^N
Examples:
1)N = 3, X =2, then the proability is 2/2^3
2) N = 4, X = 2, then the probaility is 5/16
A bit brute force, but I'd do something like this to avoid getting mired in statistics theory:
Multiply the probabilities (1 bit = 0.5, 2 bits = 0.5*0.5, etc) while looping
Keep track of each X and when you have the product of X bits, flip it and continue
Start with small example (N = 5, X=1 - 5) to make sure you get edge cases right, compare to brute force approach.
This can probably be expressed as something like Sum (Sum 0.5^x (x = 1 -> 16) (for n = 1 - 65536) , but edge cases need to be taken into account (i.e. 7 bits doesn't fit, discard probability), which gives me a bit of a headache. :-)
#Andrex answer is plain wrong as it counts some combinations several times.
For example consider the case N=3, X=1. Then the combination 101 happens only 1/2^3 times but the border calculation counts it two times: one as the sequence starting with 10 and another time as the sequence ending with 01.
His calculations gives a (1+4)/8 probability whereas there are only 4 unique sequences that have at least a single contiguous 1 (as opposed to cases such as 011):
001
010
100
101
and so the probability is 4/8.
To count the number of unique sequences you need to account for sequences that can appear multiple times. As long as X is smaller than N/2 this will happens. Not sure how you can count them tho.
For example,
n = 4 (4x1) 1 way
n = 10 (4x1, 6x1) (10x1) 2 ways
Is there any equation can express the number of way?
You have used recurrence-relation tag - yes, it is possible to use recurrence to calculate the number of ways.
P(N) = P(N-10) + P(N-6) + P(N-4)
P(0) = 1
Explanation - you can get sum N, using (N-10) cents sum and 10-cent coin and so on.
For rather large values of N recursive algorithm will work too long, so one could build dynamic programming algorithm to accelerate calculations (DP will reuse calculated values for smaller sums)
Suppose you have a list of denominations. In your case it is A = [4,6,10]. So suppose you have the following things:
A = [4,6,10]
Length of list A = N
Sum = K
The problem can be written as:
# Given the list of denominations, its length and the sum.
P(A,N,K) = 0 if N < 0 or K < 0,
1 if K = 0,
P(A,N-1,K) + P(A,N-1,k-A[N]) #A[N]-> Nth element of list
As we can see the possibility of re-using sub-problems, DP will work wonderfully.
I am trying to come up with an efficient way to list all divisors of a big factorial. Let's say 1000!. It is quite impossible with brute force. Is there an efficient approach?
I need to process them i.e. to find their sum for a programming challenge.
Find the prime factorisation of each number <= 1000. I would store this as a dictionary of prime -> power. E.g. for a single number like 24 {2: 3, 3: 1} because 24 is 2**3 * 3**1.
Find the prime factorisation of 1000!. This is the combination of the dictionaries of numbers <= 1000 combined by summing all the values for each of the keys (the primes).
You can then use equation 14 on this page as #AakashM already said.
Following are the steps for an efficient solution:
n! can be represented as :- n! = (a1^p1) (a2^p2)x...(ak^pk).
where ak is the prime divisor lesser than n and pk is the highest power
which can divide n!.
Through sieve find the prime number and the highest power can be
easily find out by :
countofpower = [n/a] + [n/a^2] + [n/a^3] +...... or ` while (n)
{
n/ = a;
ans += n
}
Count Of Factors = (ans1 +1)*(ans2 +1)*....(ansk +1)
After calculating this last step is the sum :
SUM = product of all (pow(ak,pk+1)-1)/(ak-1);
ex = 4!
4! = 2^3 * 3^1;
count of factors = (3+1)*(1+1) = 8 (1,2,3,4,6,8,12,24)
sum = ( 1 + 2 + 4 + 8)*(1 + 3) = 60.
I'm not asking about the definition but rather why the language creators chose to define modulus with asymmetric behavior in C++. (I think Java too)
Suppose I want to find the least number greater than or equal to n that is divisible by f.
If n is positive, then I do:
if(n % f)
ans = n + f - n % f;
If n is negative:
ans = n - n % f;
Clearly, this definition is not the most expedient when dealing with negative and positive numbers. So why was it defined like this? In what case does it yield expediency?
Because it's using "modulo 2 arithmetic", where each binary digit is treated independently of the other. Look at the example on "division" here
You're mistaken. When n is negative, C++ allows the result of the modulus operator to be either negative or positive as long as the results from % and / are consistent, so for any given a and b, the expression (a/b)*b + a%b will always yield a. C99 requires that the result of a % b will have the same sign as a. Some other languages (e.g., Python) require that the sign of a % b have the same sign as b.
This means the expression you've given for negative n is not actually required to work in C++. When/if n%f yields a positive number (even though n is negative), it will give ans that's less than n.