views:

219

answers:

6

When I was solving Euler project problem #15 I realized that it can be solved with the # of combinations of ways of the route from start to end. The route generated always has the same size of right or down choices (or 0s and 1s) and the right routes always have the same qty of 0s and 1s. So qty of numbers with the same qty of 0s and 1s in a binary word are C(2,1) for 1bit length C(4,2) for 2bit " " C(6,3) for 4bit " " ...

Now comes my questions: Is there a function that solves if a number has the same qty of 0s and 1s? I guess that it would be more like a logical function, I don't want to iterate all the digits or use regex (that would be worse than iterate).

**Other question is about the growth and the space between this "balanced" values?

A: 

For number which represented with N bits you have some exponential factor of such numbers with same count of zeros and ones. So you definitely have to write some code, this will require at least linear time.

For example you can do:

count = 0;
while( n &= (n -1)
  count ++;

This will give you a number of ones inside n when you will be able to compare and decide.

Artem Barger
I think [N/2]! is probably not correct ?
Paul R
You definitely right.
Artem Barger
In second thought I think it's (n + n/2 -1) choose (n - 1)
Artem Barger
@Artem: why ? you're just choosing N/2 bits out of N, surely ?
Paul R
First of all, I agreed with you and corrected myself. Second you need to pick only a half(and it's not exactly to pick) bits, since you know that half is ones and rest is zeros, so you need only decide how to arrange zeros among ones or vice versa.
Artem Barger
I guess you have downvoted me for same reason as Alexandre?
Artem Barger
+1  A: 

If I understand you correctly then you just what p = nCr where r = n/2. So:

p = n! / ((n/2)! * (n/2)!)

Paul R
this is likely to overflow. A proper way to compute binomial coefficient is by computing log(C(n,k)) with the help of loggamma.
Alexandre C.
6C3 = 20 and not 3!=6. I think you have confused a bit.
Artem Barger
@Artem: yes, my attempt to simplify the expression introduced an error - I've edited the answer now as there doesn't seem to be an obvious way to simplify.
Paul R
If the resulting answer doesn't overflow, Binomial Coeff. can be Calculated using the Prime Factorization Method (without overflowing)
st0le
+4  A: 

You are looking for a popcount function, which counts the number of set bits in a given number. Some processors have it builtin, some don't.

c=0; while (n &= (n-1)) c++;

does the job, but destroys n.

See this link for better algorithms, or google "popcount".

Alexandre C.
You won't really want to brute force this by iterating through all possible numbers and testing the population count - it really is the inverse operation that we're looking for.
Paul R
@Paul R: Quoting OP: "Is there a function that solves if a number has the same qty of 0s and 1s?", I think I answered the question. If the question is wrong, it is OP's problem.
Alexandre C.
@Alexandre: you're right - too late to remove the -1 though - sorry.
Paul R
Actually it's never late to remove it, and I guess you should more carefully read answer before downvote it, there is no one even tried to iterate over all numbers. only gave a way to check. after all there is someone thinks that P != NP, hence search not equal to identification ;)
Artem Barger
@Artem: how do you remove a vote after it's more than 5 minutes old ?
Paul R
Well I didn't knew about popcount instruction, this is really useful for this problem, thanks for that. About the inverse I thought about it and there's problems like the plenty of the sequences that have left 0s and evaluate, so I can't figure a way to evaluate a inverse.
AndreDurao
A: 

The balanced values can be found directly by imagining that you're picking your path along the way (i.e. choose to go up n times out of 2n).

There are, therefore, C(2n,n) of those values, which is 2n! / (n! * n!). The total number of values is, of course, 2^2n. Using Stirling's approximation, we find

ln n! ~= n ln n - n + ln(2*pi*n)/2
ln 2n!/(n!*n!) = ln(2n!) - 2*ln(n!) ~= 2n*ln(2) - n + ln(4*pi*n)/2 - ln(2*pi*n)

so that the fraction of values which are good, C(2n,n)/2^(2n) is

exp(2n*ln(2) - n + ln(4*pi*n)/2 - ln(2*pi*n) - 2n*ln(2)) =
exp(-n)/sqrt(pi*n)

so the number of good values decrease exponentially.

This is why it's wise to just pick them out directly instead of test.

But if you really want to test, there are various bit-counting methods here. (Kernighan's is probably the fastest--note however that he wasn't the first person to notice it, and that an equivalent algorithm is already posted here!)

Rex Kerr
Yep, I found Kernighan's method included in that popcount list, thanks for the explanation about the decrease of good values. I started a graphics of values from 2^2 .. 2^10 centered, after that only the center values (till 2^16) appears in a 2^10 width graphic.http://img839.imageshack.us/img839/6369/distribuicao.png
AndreDurao
+2  A: 

As a follow up to Paul R's answer, there is a simplification of the formula for the central binomial coefficient, see http://mathworld.wolfram.com/CentralBinomialCoefficient.html

p = n! / ((n/2)!)² = 2n/2 (n-1)!! / (n/2)!

k!! is the "double factorial", which means you skip every other number when calculating: k!! = k * (k-2) * (k-4) * ... (as long as the factor is positive).

For your calculation a lot of numbers will cancel out (you can use the gcd for this when calculating numerator and denominator simultaneously)

Landei
A: 

You could use a look-up table mapping an n-bt number to its 1-count. For example, if you always had 23-bit unsigned integers a lookup table of 16 bits and 7 bits would allow you to split the number and add the one-count from the lookup tables for the 16 and 7 bit portions. (The 7-bit look-up table could be just a section of the 16 bit table).

Paddy3118
well, I don't know if I understand it right. But only to fill the table costs at least O(n), I guess that ain't better way than popcount to do this
AndreDurao