Adjacent Bit Counts - algorithm

here is the problem from spoj that states
For a string of n bits x1,x2,x3,...,Xn
the adjacent bit count of the string
(AdjBC(x)) is given by
X1*X2 + X2*X3 + X3*X4 + ... + Xn-1 *
Xn
which counts the number of times a 1
bit is adjacent to another 1 bit. For
example:
AdjBC(011101101) = 3
AdjBC(111101101) = 4
AdjBC(010101010) = 0
and the question is : Write a program which takes as input integers n and k and returns the number of bit strings x of n bits (out of 2ⁿ) that satisfy AdjBC(x) = k.
I have no idea how to solve this problem. Can you help me to solve this ?
Thanks

Often in combinatorial problems, it helps to look at the set of values it produces. Using brute force I calculated the following table:
k 0 1 2 3 4 5 6
n +----------------------------
1 | 2 0 0 0 0 0 0
2 | 3 1 0 0 0 0 0
3 | 5 2 1 0 0 0 0
4 | 8 5 2 1 0 0 0
5 | 13 10 6 2 1 0 0
6 | 21 20 13 7 2 1 0
7 | 34 38 29 16 8 2 1
The first column is the familiar Fibonacci sequence, and satisfies the recurrence relation f(n, 0) = f(n-1, 0) + f(n-2, 0)
The other columns satisfies the recurrence relation f(n, k) = f(n - 1, k) + f(n - 1, k - 1) + f(n - 2, k) - f(n - 2, k - 1)
With this, you can do some dynamic programming:
INPUT: n, k
row1 <- [2,0,0,0,...] (k+1 elements)
row2 <- [3,1,0,0,...] (k+1 elements)
repeat (n-2) times
for j = k downto 1 do
row1[j] <- row2[j] + row2[j-1] + row1[j] - row1[j-1]
row1[0] <- row1[0] + row2[0]
swap row1 and row2
return row2[k]

As a hint you can split it up into two cases: numbers ending in 0 and numbers ending in 1.
def f(n, k):
return f_ending_in_0(n, k) + f_ending_in_1(n, k)
def f_ending_in_0(n, k):
if n == 1: return k == 0
return f(n - 1, k)
def f_ending_in_1(n, k):
if n == 1: return k == 0
return f_ending_in_0(n - 1, k) + f_ending_in_1(n - 1, k - 1)
This gives the correct output but takes a long time to execute. You can apply standard dynamic programming or memoization techniques to get this to perform fast enough.

I am late to the party, but I have a linear time complexity solution.
For me this is more of a mathematical problem. You can read the detailed solution in this blog post written by me. What follows is a brief outline. I wish I could put some LaTeX, but SO doesn't allows that.
Suppose for given n and k, our answer is given by the function f(n,k). Using Beggar's Method, we can arrive at the following formula
f(n,k) = SUM C(k+a-1,a-1)*C(n-k+1-a,a), where a runs from 1 to (n-k+1)/2
Here C(p,q) denotes binomial coefficients.
So to get our answer, we have to calculate both the binomial coefficients for each value of a. We can calculate the binomial table beforehand. This approach will then given our answer in O(n^2) since we have to calculate the table.
We can improve the time complexity by using the recursion formula C(p,q) = (p * C(p-1,q-1))/q to calculate the current value of binomial coefficients from their values in previous loop.
Our final code looks like this:
long long x=n-k, y=1, p=n-k+1, ans=0;
ans += x*y;
for(int a=2; a<=p/2; a++)
{
x = (x*(p-2*a+1)*(p-2*a+2))/(a*(p-a+1));
y = (y*(k+a-1))/(a-1);
ans += x*y;
}
You can find the complete accepted solution in my GitHub repository.

Related

Is there any algorithm to improve my code?

SEAWEED
You're given k days and n seaweed.
(1 ≤ n ≤ 1000, 1 ≤ k ≤ 10^17)
At the very first day, you have n seaweed at level 1
The next day, that n seaweed will reproduce, every n seaweed at level i will reproduce n*i seaweed at level 1, these level 1 seaweed will start reproduce after the day end.
Every seaweed at level i will become level i+1.
After k days, return the total number of seaweed
(im very sorry, if you dont understand the problem, i'm very bad at translating)
EXAMPLE:
INPUT : 3 3
OUTPUT : 39
EXPLANATION:
DAY 0 : 3 SEAWEED
DAY 1 : 3 Level 1 , 3 Level 2 ...
Total seaweed at day 1 = 6
DAY 2 : 3 + 3 * 2 Level 1 (there are 3 level 1 and 3 level 2, so 3 * 1 + 3 * 2 = 9), 3 Level 2 , 3 Level 3
Total seaweed at day 2 = 15
DAY 3: 9 + 3 * 2 + 3 * 3 = 24 (at day 2 there is 9 level 1, 3 level 2 and 3 level 3) Level 1 , 3 + 3*2 = 9 Level 2 , 3 Level 3 , 3 Level 4
Total seaweed at day 3 = 39
TOTAL OF SEAWEED : 39
Can you help me find any algorithm for this problem? and shorten my problem into one sentence
My code doesn't seem so fast
Here's my code for the problem:
def solver(n,k):
storage = [n]
for i in range(k):
reproduction = 0
for j in range(len(storage)):
reproduction += storage[j]*(j+1)
storage = [reproduction] + storage
return sum(storage)%(10**9+7)
Some more test case:
INPUT : n = 4, k = 3
OUTPUT : 52
INPUT : n = 5, k = 5
OUTPUT : 445
Solution might be expressed through Fibonacci numbers:
solver(n,k) = n*Fib(2*k+1)
and Fibonacci numbers for extremely high k values (using modulo 10**9+7) might be calculated with matrix exponentiation method here
The first insight is that the function is linear in n. You can imagine each of the n initial seaweed plants as a separate lineage; their descendants do not interfere with each other, so if you double n, you double the answer. So if you solve f(1, k) then you can get f(n, k) simply by multiplying by n. You could -- by some slow calculation -- make a table of values of f(1, k) for many values of k, then compute f(n, k) for any (n, k) that is requested.
The second insight is to work out e.g. f(1, 5) on paper and see the patterns in the numbers. If you are a mathematician at heart, you will recognise some terms from the Fibonacci sequence. (If you are really a mathematician at heart, you will prove the pattern.) Then you can write the formula for f(n, k), and some fast code to calculate it.

Enumerating all possible permutations when each element belongs to a set

Problem: You are given a natural number N and a set of elements of size M. Your task is to generate all possible values of a list of size N where each element belongs to set M (both with or without repetition).
Example: Let N = 2 and M = < 0, 1 >.
With repetition: N = [0,1] or N = [1,0] or N = [0,0] or N = [1,1]
Without repetition: N = [1,0] or N = [0,1]
I came up with solution (EDIT - which is wrong) for with repetition as follows.
It is in pseudocode so that it isn't biased to anyone without knowledge of the language.
Let I be an auxillary list of size N.
Let l denote the last value changed in I initialized as value N.
Fill I with value 1.
while l != 0
for i = 1 to N
N[i] = M[I[i]]
do_something(N)
if I[l] != M
I[l] += 1
elseif l == 1
break // So that it does not become not defined in else clause
else
l -= 1
I[l] += 1
It takes O(N^2 * M) time and O(N + M) space. If you have better one then please post it.
I was not able to come up with a good solution for without repetition case.
You would see that your algorithm has a problem if you had actually tried it on some very simple cases, like for example the one you actually gave as an example, with M=N=2. (Why didn't you do this first?) It will not generate the list 1 0.
Why? Because after decrementing l and incrementing the new I[l], you never decrease any of the later (further to the right) values in I[]. So e.g. for N=5 you would generate only the permutations
0 0 0 0 0
0 0 0 0 1
0 0 0 1 1
0 0 1 1 1
0 1 1 1 1
1 1 1 1 1

Approach for Problems which appeared in 101 Hack June Challenge contest [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I gave 101 Hack June Challenge contest but there were two problems which I wasn't able to solve. Can anyone give me some hint on how to approach these two questions:
Q1. Assignment Problem
Calvin has a math assignment at school where he has to evaluate a lot of expressions. Calvin decides to not to waste much of his time. There are ‘M’ expressions overall. By looking at Susie’s answers, Calvin has figured that the answers to all questions form a non decreasing sequence.
He decides that all his answers are going to be between 1 and ‘N’ (inclusive). He fills his answer sheet with a random non-decreasing sequence of length ‘M’ where each element is between 1 and ‘N’.
Here is the part where the real problem starts for Calvin. He does not want to choose a large value of N, because, he will have a lot of options to choose from. Also, if he chooses a very small value of N, a lot of answers would become equal and the teacher will become suspicious.
If x = max1 ≤ i ≤ N (frequency (i)), frequency (i) being the number of times i occurs in the sequence of ‘M’ values he picked. Calvin wants to find out expected value of x. Help him solve the problem.
For example, if M = 3 & N = 3, the possible sequences are:
1 1 1 (x = 3)
1 1 2 (x = 2)
1 1 3 (x = 2)
1 2 2 (x = 2)
1 2 3 (x = 1)
1 3 3 (x = 2)
2 2 2 (x = 3)
2 2 3 (x = 2)
2 3 3 (x = 2)
3 3 3 (x = 3)
expected value of x = 2.2
Input Format
The first line contains an integer T which refers to the number of test cases. T lines follow, each containing 2 numbers, M and N for the corresponding test cases.
Constraints
T ≤ 15
1 ≤ M ≤ 250
1 ≤ N ≤ 10^9
Output Format
Output T lines, each containing answer to the corresponding test case. Error of upto 10^-3 is allowed.
Sample Input
4
1 5
3 3
2 9
9 6
Sample Output
1.0000000000
2.2000000000
1.2000000000
4.3146853147
Q2. GCD mocktail
The Rebel Alliance and the Galactic Empire are engaged in an epic battle in the skies above Endor. The grand setup has d-dimensional board with each dimension of length ‘N’, (i.e) N x N… (d times). Each cell (i1, i2, …id) has the gcd (i1, i2, …id) written on it.
Now, the game begins. A random integer L is chosen and the first person to sum up the Lth power of each number modulo 30000001 wins the game.
Rebel Alliance needs some help and pings you. If they win, you get a million dollars for it. Can you help?
Input Format
There are several test cases. The first line contains the number of test cases T. Then T test cases follow. Each test case is given in the following format.
N and d are given in the first Line.
Q is given in the second line.
Each of the next Q lines contain an integer L.
Constraints
0 <= T <= 10
1 <= N <= 107
1 <= d <= 1000
0 <= L <= 100
0 <= Q <= 50
Output Format
For each test case, output Q lines, indicating the answer.
Sample Input
3
3 2
4
0
1
2
3
5 1
3
0
1
2
6 3
2
2
3
Sample Output
9
12
20
42
5
15
55
421
975
This are links to problems on website:
Q1. https://www.hackerrank.com/contests/101june13/challenges/assignment
Q2. https://www.hackerrank.com/contests/101june13/challenges/gcd-mocktail
The contest has ended, so I guess it's not cheating by asking some help on Stackoverflow.
For Q2:
Let's start by counting how many times each value appears in such an array:
1 - appears whenever the positions are coprime. This is hard to count directly, so let's leave it out for now.
2 - appears when all the positions are a multiple of 2. How many combinations of numbers from [1, N] are all multiples of 2, allowing repeats? There are N / 2 possibilities for the first value, and as many for all of the other d values, so (N / 2)^d possibilities. However, we have also counted those that are all a LARGER multiple, which would give a larger GCD. So we must subtract those formed from nothing but larger multiples, that is (N / 4)^d + (N / 6)^d + ...
k <= N - can be deduced the same as above. Let num(k) be this value.
Therefore, 1 will appear N^d - num(2) - num(3) - ... times.
So you have to compute the sum:
S = num(1) + num(2) * 2^L + num(3) * 3^L + ...
This gives an O(N^2 * L) or O(N^2 log L) solution if you implement it directly, which is too slow, since N can go up to 10^7. We have to do a lot better.
Let's write out S:
S = N^d - num(2) - num(3) - ...
+ num(2) * 2^L + num(3) * 3^L + ...
= N^d + num(2)(2^L - 1) + num(3)(3^L - 1) + ...
= N^d + [(N / 2)^d - (N / 4)^d - ...](2^L - 1)
+ [(N / 3)^d - (N / 6)^d - ...](3^L - 1)
+ [(N / 4)^d - (N / 8)^d - ...](4^L - 1)
+ ...
A lot of terms repeat themselves, but so far I'm not sure where to go from here. I'll leave this up in case it helps anyone take it further and I'll delete it if someone posts a complete solution.
For Q1, imagine if you knew the function f(N, M, K) giving you the # of ways that a non-decreasing sequence of M integers in the range 1 to N could have at most K repeated. Then f(N, M, K) - f(N, M, K-1) gives you the number that have exactly K repeated. And now we get the exact distribution, giving us the exact answer.
Now f(N, M, K) obviously is 0 if 0 = K and 0 < M. And f(N, 0, 0) is trivially 1. (There is only one empty set.) Add in the fact that f(N, M, K) = f(N, M, K-1) + f(N-1, M-K, K) and we're all set to solve with dynamic programming. (The main challenge is that you're probably going to run out of floating point range if N is a billion, and M is 250...)
I'd have to think about Q2. I have an idea how to do it, but it isn't quite as simple for me.

number of integral solutions

Question from the interview at f2f interview at MS:
Determine the number of integral solutions of
x1 + x2 + x3 + x4 + x5 = N
where 0 <= xi <= N
So basically we need to find the number of partitions of N in at most 5 parts
Supposed to be solved with paper and pencil. Did not make much headway though, does anybody have a solution for this?
Assume numbers are strictly > 0.
Consider an integer segment [0, N]. The problem is to split it into 4 segments of positive length. Imagine we do that by putting 4 splitter dots between adjacent numbers. How many ways to do that ? C(N-1, 4).
Now, some numbers can be 0-s. Let k be number of non-zero numbers. We can choose them in C(5,k) ways, for each having C(N-1, k) splittings. Accumulating by all k in [0,5] range, we get
Sum[ C(5,k) * C(n-1,k); k = 0 to 5]
#Grigor Gevorgyan indeed gives the right way to figure out the solution.
think about when
1 <= xi
that's exactly dividing N points into 5 segments. it's equivalent to insert 4 "splitter dots" out of N-1 possible places ( between adjacent numbers). So the answer is C(N-1,4)
then what about when
0 <= xi
?
If you have the solution of X+5 points in
1 <= xi
whose answer is C(N-1,4)=C(X+5-1,4)=C(X+4,4)
then you simply remove one point from each set, and you have a solution of X points, with
0 <= xi
which means,the answer now is exactly equal to C(X+4,4)
Topcoder tutorials
Look for the section "Combination with repetition" : The specific case is explained under that section with diagrmatic illustration .(A picture is worth quite a few words!)
You have the answer here.
It is classical problem -
Number of options to put N balls in M boxes = c(M+N-1,N).
The combinations solution is more appropriate if a pen and paper solution was asked. It's also the classic solution. Here is a dynamic programming solution.
Let dp[i, N] = number of solutions of x1 + x2 + ... +xi = N.
Let's take x1 + x2 = N:
We have the solutions:
0 + N = N
1 + N - 1 = N
...
N + 0 = N
So dp[2, N] = N + 1 solutions.
Let's take x1 + x2 + x3 = N:
We have the solutions:
0 + (0 + N) = N
0 + (1 + N - 1) = N
...
0 + (N + 0) = N
...
Notice that there are N + 1 solutions thus far. Moving on:
1 + (0 + N - 1) = N
1 + (1 + N - 2) = N
...
1 + (N - 1 + 0) = N
...
Notice that there are another N solutions. Moving on:
...
N - 1 + (0 + 1) = N
N - 1 + (1 + 0) = N
=> +2 solutions
N + (0 + 0) = N
=> +1 solution
So we have dp[3, N] = dp[2, N] + dp[2, N - 1] + dp[2, N - 2] + ... + dp[2, 0].
Also notice that dp[k, 0] = 1
Since for each row of the matrix we need N summations, the complexity for computing dp[k, N] is O(k*N), which is just as much as would be needed for the combinatorics solution.
To keep the complexity for each row O(N), store s[i] = sum of the first i elements on the previous row. The memory used can also be reduced to O(N).

Rectangular region in an array

Given an N*N matrix having 1's an 0's in them and given an integer k,what is the best method to find a rectangular region such that it has k 1's in it ???
I can do it with O(N^3*log(N)), but sure the best solution is faster. First you create another N*N matrix B (the initial matrix is A). The logic of B is the following:
B[i][j] - is the number of ones on rectangle in A with corners (0,0) and (i,j).
You can evaluate B for O(N^2) by dynamic programming: B[i][j] = B[i-1][j] + B[i][j-1] - B[i-1][j-1] + A[i][j].
Now it is very easy to solve this problem with O(N^4) by iterating over all right-bottom (i=1..N, j=1..N, O(N^2)), left-bottom (z=1..j, O(N)), and right-upper (t=1..i, O(N)) and you get the number of ones in this rectangular with the help of B:
sum_of_ones = B[i][j] - B[i][z-1] - B[t-1][j] + B[t-1][z-1].
If you got exactly k: k==sum_of_ones, then out the result.
To make it N^3*log(N), you should find right-upper by binary search (so not just iterate all possible cells).
Consider this simpler problem:
Given a vector of size N containing only the values 1 and 0, find a subsequence that contains exactly k values of 1 in it.
Let A be the given vector and S[i] = A[1] + A[2] + A[3] + ... + A[i], meaning how many 1s there are in the subsequence A[1..i].
For each i, we are interested in the existence of a j <= i such that S[i] - S[j-1] == k.
We can find this in O(n) with a hash table by using the following relation:
S[i] - S[j-1] == k => S[j-1] = S[i] - k
let H = an empty hash table
for i = 1 to N do
if H.Contains (S[i] - k) then your sequence ends at i
else
H.Add(S[i])
Now we can use this to solve your given problem in O(N^3): for each sequence of rows in your given matrix (there are O(N^2) sequences of rows), consider that sequence to represent a vector and apply the previous algorithm on it. The computation of S is a bit more difficult in the matrix case, but it's not that hard to figure out. Let me know if you need more details.
Update:
Here's how the algorithm would work on the following matrix, assuming k = 12:
0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0
Consider the first row alone:
0 1 1 1 1 0
Consider it to be the vector 0 1 1 1 1 0 and apply the algorithm for the simpler problem on it: we find that there's no subsequence adding up to 12, so we move on.
Consider the first two rows:
0 1 1 1 1 0
0 1 1 1 1 0
Consider them to be the vector 0+0 1+1 1+1 1+1 1+1 0+0 = 0 2 2 2 2 0 and apply the algorithm for the simpler problem on it: again, no subsequence that adds up to 12, so move on.
Consider the first three rows:
0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0
Consider them to be the vector 0 3 3 3 3 0 and apply the algorithm for the simpler problem on it: we find the sequence starting at position 2 and ending at position 5 to be the solution. From this we can get the entire rectangle with simple bookkeeping.

Resources