Compute rand7() using rand5() - algorithm

I have a solution for the problem to generate rand7() using only rand5().
One of the solution states:
5 * rand5() + rand5() would generate number 0 - 24 in equal probability so we just need to loop until we get a number < 21 ( 3 * 7 ) than % 7 to get the right answer between 0 - 6.
My question is why couldn't we just do 3 * rand5() + rand5() to generate number < 14 ( 2 * 7 ) instead?

If X and Y are independent and uniformly distributed on the set S_5 = {0,1,2,3,4}, then
5*X + Y is uniformly distributed on the set {0,...,24}, but
3*X + Y is not uniformly distributed on {0,...,16} and neither is its restriction on {0,...,13}
It's easy to see that (1) is indeed the case, because f(x,y) = 5*x + y is a bijection between S_5 x S_5 and S_25.
If we look at the distribution of 3*X + Y we get:
>>> Counter(3*x + y for x in range(5) for y in range(5))
Counter({3: 2, 4: 2, 6: 2, 7: 2, 9: 2, 10: 2, 12: 2, 13: 2, 0: 1, 1: 1, 2: 1, 5: 1, 8: 1, 11: 1, 14: 1, 15: 1, 16: 1}
The results 3, 4, 6, 7, 9, 10, 12, 13 are twice as likely as 1, 2, 5, 8 or 11. More proof:
>>> def rand7():
... x = 3*rand5() + rand5()
... if x < 14: return x % 7
... return rand7()
...
>>> Counter(rand7() for _ in xrange(100000))
Counter({6: 18219, 3: 18105, 4: 13734, 5: 13715, 2: 13634, 0: 13560, 1: 9033}
6 and 3 have a 4/22 ~ 18.2% chance of occuring, 4, 5, 2 and 0 have an 3/22 ~ 13.6% chance and 1 only has a 2/22 ~ 9.1% chance. That's one rigged dice.

3 * rand5() + rand5()
is not uniformly distributed. For example, it generates 0 in only one way, but 3 two ways, so 3 is more likely to occur than 0.
It's just like 2 * rand5() * rand5(), 4 * rand5() + rand5(), etc.
But 5 * rand5() + rand5() is uniformly distributed.
It is like generating two random digits of a base-5 number.
00 => 0
01 => 1
02 => 2
03 => 3
04 => 4
10 => 5
11 => 6
12 => 7
...
There is only and only one way to generate each number from 0 to 24.

In order to have a uniform distribution, the contributions of the two random numbers have to be independent. This means the range of the one must not overlap the range of the other, nor must there be any gaps.
In your proposed method there are two ways to get a 3 for example: the first random number returns 1 and the second returns 0, or the first returns 0 and the second returns 3. This makes it twice as likely to occur than a result of 0, which can only occur if both random numbers are 0.

Related

Finding the maximum possible sum/product combination of integers

Given an input of a list of N integers always starting with 1, for example: 1, 4, 2, 3, 5. And some target integer T.
Processing the list in order, the algorithm decides whether to add or multiply the number by the current score to achieve the maximum possible output < T.
For example: [input] 1, 4, 2, 3, 5 T=40
1 + 4 = 5
5 * 2 = 10
10 * 3 = 30
30 + 5 = 35 which is < 40, so valid.
But
1 * 4 = 4
4 * 2 = 8
8 * 3 = 24
24 * 5 = 120 which is > 40, so invalid.
I'm having trouble conceptualizing this in an algorithm -- I'm just looking for advice on how to think about it or at most pseudo-code. How would I go about coding this?
My first instinct was to think about the +/* as 1/0, and then test permutations like 0000 (where length == N-1, I think), then 0001, then 0011, then 0111, then 1111, then 1000, etc. etc.
But I don't know how to put that into pseudo-code given a general N integers. Any help would be appreciated.
You can use recursive to implement the permutations. Python code below:
MINIMUM = -2147483648
def solve(input, T, index, temp):
# if negative value exists in input, remove below two lines
if temp >= T:
return MINIMUM
if index == len(input):
return temp
ans0 = solve(input, T, index + 1, temp + input[index])
ans1 = solve(input, T, index + 1, temp * input[index])
return max(ans0, ans1)
print(solve([1, 4, 2, 3, 5], 40, 1, 1))
But this method requires O(2^n) time complexity.

Last digit of a large number (Ruby) how to deal with NaN?

Here's my code:
def last_digit(n1, n2)
array = (n1.to_i ** n2.to_i).to_s.split("")
array[-1].to_i
end
TEST: The last decimal digit of (2^200)^(2^300), which has over 10^92 decimal digits, is 6
I'm trying to return the last digit of a last number and I'm sure this correct but when I run tests 2 return as failing.
I think it's due to the numbers being too large, how do I get this code to remain accurate no matter how large it gets.
And also how do I deal with NaN, I've searched and struggled to find anything useful.
Thanks for your help.
There's an effective algorithm which assumes that only the last digit of a number being powered matters. Please, try it out on your tests and feel free to correct any flaw in this implementation that you'll find by running them
def digit_of_power(digit, n)
digit = digit % 10
case digit
when 0, 1, 5, 6 then digit
else
digit_of_square = digit * digit
if n.even?
digit_of_power(digit_of_square, n / 2)
else
digit * digit_of_power(digit_of_square, (n - 1) / 2) % 10
end
end
end
This is my solution
def last_digit(n1, n2)
return 1 if n2 == 0
return 0 if n1 == 0
exp = (n2 % 4 == 0) ? 4 : n2 % 4
return (n1**exp) % 10
end
You might want to read this article (finding the last digit of a power) for a more detailed explanation of the solution to this math problem.
Take a look at the following table:
You can see that the maximum length for cycle repetition is 4.
For instance:
2 * 2 = 4
4 * 2 = 8
8 * 2 = 16
16 * 2 = 32
32 * 2 = 64
64 * 2 = 128
128 * 2 = 256
256 * 2 = 512
The last digit in 32 is 2 ( as it is in 512), meaning that after multiplying the digit by 4, it will repeat itself.
The algorithm follows this logic:
You reduce the exponent, knowing that if it is divisible by 4, its new value is 4 because multiplying it 4 times gives you the last digit according to the table above. Otherwise, its value is n2 % 4.
As a final step you do this n1^exp % 10 because you only need the last number.
Note:
I tested it successfully with large numbers.
n1 = 38710248912497124917933333333284108412048102948908149081409204712406
n2 = 226628148126342643123641923461846128214626
By the way, I realize I am late in responding to your question. I just think it might be helpful for someone else someday.
Code
ENDINGS = [[0,0,0,0], [1,1,1,1], [2,4,8,6], [3,9,7,1], [4,6,4,6],
[5,5,5,5], [6,6,6,6], [7,9,3,1], [8,4,2,6], [9,1,9,1]]
def last_digit_of_power(digit, power)
return 1 if power.zero?
ENDINGS[digit][(power-1) % 4]
end
Examples
Let's try it for power equal to 5 and then 6.
(5..6).each do |power|
puts "\npow = #{power}"
(0..9).each {|digit| puts "#{digit}: #{last_digit_of_power(digit, power)}"}
end
pow = 5
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9
pow = 6
0: 0
1: 1
2: 4
3: 9
4: 6
5: 5
6: 6
7: 9
8: 4
9: 1
Explanation
This uses the same algorithm as employed by #Igor, but I've implemented it differently. It is known (and can be easily demonstrated) that the last digit of each digit 0-9 taken to increasing powers cycles among at most 4 digits. Consider the digit 3, for example. Since
[1,2,3,4,5].map { |power| 3**power }
#=> [3, 9, 27, 81, 243]
the last digits of 3 taken to each of those 5 powers is [3, 9, 7, 1, 3]. Since the last digit of 3**5 is the same as the last digit of 3**1, we infer than the last digit of 3**6 will be the same as the last digit of 3**(6-4) (3**2), which is 9, and so on.
Now suppose we wished to calculate the last digit of 3**15. We see that it will be the same as the last digit of 3**(15-4) (3**11), which in turn will equal the last digit of 3**7 and then the last digit 3**3, but we already know the last of these, which is 7. It follows that the last digit of 3**power is
[3, 9, 7, 1][(power-1) % 4]
ENDINGS provides the last digits for powers 1-4 for each of the digits 0-9. Note the cycle length is 1 for 0, 1, 5 and 6, is 2 for 4 and 9 and is 4 for 2, 3, 7 and 8. It's most convenient, however, to use a cycle length of 4 for all 10 digits.
ENDINGS[digit] equals the four endings of digit taken to the powers of 1, 2, 3 and 4. The last digit of the digit digit taken to the power power therefore equals
ENDINGS[digit][(power-1) % 4]

What is the meaning of "exclusive" and "inclusive" when describing number ranges?

Simple question but, I see exclusive and inclusive when referring to number ranges.
For example, this is a line from an algorithms book:
The following function prints the powers of 2 from 1 through n (inclusive).
What is meant by this? What makes a number range inclusive or exclusive?
In Computer Science, inclusive/exclusive doesn't apply to algorithms, but to a number range (more specifically, to the endpoint of the range):
1 through 10 (inclusive)
1 2 3 4 5 6 7 8 9 10
1 through 10 (exclusive)
1 2 3 4 5 6 7 8 9
In mathematics, the 2 ranges above would be:
[1, 10]
[1, 10)
You can remember it easily:
Inclusive - Including the last number
Exclusive - Excluding the last number
The following function prints the powers of 2 from 1 through n (inclusive).
This means that the function will compute 2^i where i = 1, 2, ..., n, in other words, i can have values from 1 up to and including the value n. i.e n is Included in Inclusive
If, on the other hand, your book had said:
The following function prints the powers of 2 from 1 through n (exclusive).
This would mean that i = 1, 2, ..., n-1, i.e. i can take values up to n-1, but not including, n, which means i = n-1 is the highest value it could have.i.e n is excluded in exclusive.
In simple terms, inclusive means within and the number n, while exclusive means within and without the number n.
Note: that each argument should be marked its "clusivity"/ "participation"
# 1 (inclusive) through 5 (inclusive)
1 <= x <= 5 == [1, 2, 3, 4, 5]
# 1 (inclusive) through 5 (exclusive)
1 <= x < 5 == [1, 2, 3, 4]
# 1 (exclusive) through 5 (inclusive)
1 < x <= 5 == [2, 3, 4, 5]
# 1 (exclusive) through 5 (exclusive)
1 < x < 5 == [2, 3, 4]
The value of n inclusive 2 and 5 [2,5]
including both the numbes in case exclusive only the first is included
programming terms n>=2 && n<=5
The value of of n exlcusive of 2 and 5 [2,5)
n>=2 && n<5

How to check if a given number is of the form x^y?

I'm preparing for my interviews and came across this question:
Write a program to check if a number n is of x^y form. It is known that n, x and y are integers and that x and y are greater than 2.
I thought of taking log and stuff but couldn't certainly figure out how to check if the number is of the form. Could any of you please help? :)
"Taking the log and stuff" is the way to go. Note that N > 1 is never a^b for integer a and b > log_2(N). So you can check floor(N^(1/b))^b = N for each integer b between 2 and log_2(N). You have to do about log(N) many exponentiations, each of which produces a number at most the size of N.
This is far faster than #dasblinkenlight's solution, which requires you to factor N first. (No polynomial-time algorithm---that is, polynomial in the number of bits in N, is known for integer factorisation. However, integer exponentiation with a small exponent can be done in polynomial time.)
One way to solve this would be to factorize n, count the individual factors, and find the greatest common denominator of the counts. If GCD is 1, the answer is "no". Otherwise, the answer is "yes".
Here are some examples:
7, prime factor 7 (one time). We have one factor repeated once. Answer "no", because the GCD is 1.
8, prime factors 2 (3 times). We have one factor with the count of three. Answer "yes", because GCD is 3.
144, prime factors 2 (4 times) 3 (2 times). GCD of 4 and 2 is 2, so the answer is "yes".
72, prime factors 2 (3 times) 3 (2 times). GCD of 3 and 2 is 1, so the answer is "no".
There are a lot of good answers, but I see modulo arithmetics is still missing.
Depending on the magnitude of the numbers to check, it might be useful to classify them by their last bits. We can easily create a table with possible candidates.
To show how it works, let us create such a table for 4 last bits. In that case we have 16 cases to consider:
0^2, 0^3, ... : 0 mod 16
1^2, 1^3, ... : 1 mod 16
2^2, 2^3, ... : 0, 4, 8 mod 16
3^2, 3^3, ... : 9, 11, 1, 3 mod 16
4^2, 4^3, ... : 0 mod 16
5^2, 5^3, ... : 9, 13, 1, 5 mod 16
6^2, 6^3, ... : 4, 8, 0 mod 16
7^2, 7^3, ... : 1, 7 mod 16
8^2, 8^3, ... : 0 mod 16
9^2, 9^3, ... : 9, 1 mod 16
10^2,10^3, ... : 4, 8, 0 mod 16
11^2,11^3, ... : 9, 3, 1, 11 mod 16
12^2,12^3, ... : 0 mod 16
13^2,13^3, ... : 9, 5, 1, 13 mod 16
14^2,14^3, ... : 4, 8, 0 mod 16
15^2,15^3, ... : 1, 15 mod 16
The table is more useful the other way round; which bases x are possible for a given number n = x^y.
0: 0, 2, 4, 6, 8, 10, 12, 14 mod 16
1: 1, 3, 5, 7, 9, 11, 13, 15
2: -
3: 3, 11
4: 2, 6, 10, 14
5: 5, 13
6: -
7: 7
8: 2, 6, 10, 14
9: 3, 5, 9, 11, 13
10: -
11: 3, 11
12: -
13: 5, 13
14: -
15: 15
So, just by looking at the four last bits over one quarter of numbers can be discarded immediately.
If we take number 13726423, its remainder by 16 is 7, and thus if it is of the form we are interested in, it must be (16 n+7)^y.
For most numbers the number of divisors to try is quite limited. In practice, the table could me much larger, e.g., 16 bits.
A simple optimization with binary numbers is to remove the trailing zeros. This makes it unnecessary to worry about even numbers, and y must be a factor of the number of the zeros removed.
If we still have too much work, we can create another modulo table. The other could be, e.g. modulo 15. The equivalent table looks like this:
0: 0
1: 1, 2, 4, 7, 8, 11, 13, 14
2: 2, 8
3: 3, 12
4: 2, 4, 7, 8, 13
5: 5
6: 3, 6, 9, 12
7: 7, 13
8: 2, 8
9: 3, 9, 12
10: 5, 10
11: 11
12: 3, 12
13: 7, 13
14: 14
As our number from the previous example (13726423) is 13 modulo 15, then x = (15 m +7) or (15 m +13). As there are no common factors in 15 and 16, the valid numbers are 240 p + 7 and 240 p + 103. By two integer divisions and two table lookups we have managed to limit the possible values of x to 1/120 of numbers.
If the tables are largish, the number of possible x s is easy to limit to a very low number. For example, with tables of 65536 and 65535 elements the cycle is 4294901760, so for any number below approximately 1.6 x 10^19 the two tables give a short unique list of possible values of x.
If you can factor n, then it is easy to find an answer by examining the multiplicities of the factors. But the usual use for determining if a number is a perfect power is as a preliminary test for some factoring algorithms, in which case it is not realistic to find the factors of n.
The trick to determining if a number is a perfect power is to know that, if the number is a perfect power, then the exponent e must be less than log2 n, because if e is greater then 2e will be greater than n. Further, it is only necessary to test prime es, because if a number is a perfect power to a composite exponent it will also be a perfect power to the prime factors of the composite component; for instance, 215 = 32768 = 323 = 85 is a perfect cube root and also a perfect fifth root. Here is pseudocode for a function that returns b if there is some exponent e such that be = n or 0 if there is not; the function root(e,n) returns the e-th root of n:
function perfectPower(n)
for p in primes(log2(n))
b = floor(root(p,n))
if b**p == n return b
return 0
I discuss this function at my blog.
Alternatively, if factorization is too hard, you can exploit your maths library and try many values of x or y until you find one that works.
Trying for y will be less work, if you have an operation "y-th root of n" available (it could be masquerading under the name of "x to the power of 1/y"). Just try all integer values of y larger than 2 until either you find one that gives an integer answer, or the result drops below 2. If n is a standard 32-bit integer, then it will take no more than 32 attempts (and, more generally, if n is a m-bit integer, then it will take no more than m attempts).
If you do not have "y-th root of n" available, you can try all x's with the operation "log base x of n", until you get an integer answer or the result drops below 2. This will take more work since you need to check all values up until square root of x. I think it should be possible to optimize this somehow and "home in" on potential integer results.
The exponent y is easily bounded 2 ≤ y ≤ log_2(n) . Test each y in that range. If it exists, x will be the integer yth root of n.
The point is while x determines y and vice versa, the search space for y is much smaller, so you should search y rather than x (which could be as large as sqrt(n)).

Shortest Bit Sequence Logic

I am trying to understand how does the shortest bit sequence work. I mean the logic. I need to create a program for it but don't know actually what is this shortest bit sequence. I tried to google but in vain. I came across this Question on SO but I cant understand anything from it. Can anyone explain it to me or guide me somewhere where I can understand the logic behind this?
As Jan Dvorak pointed out in the comments, it's simply a number written in base -2.
Consider your example [0, 1, 1, 1, 1, 1, 1].
The exponents of -2 are the same as for 2, but with alternating signs:
(-2)^0 = 1
(-2)^1 = -2
(-2)^2 = 4
(-2)^3 = -8
(-2)^4 = 16
(-2)^5 = -32
(-2)^6 = 64
...
In the bit sequence notation lowest exponents come first, that is the order is reversed compared to ordinary binary numbers.
[0, 1, 1, 1, 1, 1, 1] = 0 * (-2)^0 +
1 * (-2)^1 +
1 * (-2)^2 +
1 * (-2)^3 +
1 * (-2)^4 +
1 * (-2)^5 +
1 * (-2)^6
which gives (from the bottom up)
[0, 1, 1, 1, 1, 1, 1] = 64 - 32 + 16 - 8 + 4 - 2 = 42
def solution(A):
n=len(A)
result=0
if n==0:
return -1
for i in range(n):
result+=(A[i]*pow(-2,i))
return result
print solution([1,0,0,1,1])

Resources