If you express some positive integer in binary with no leading zeros and replace every 1 with a ( and every 0 with a ), then will all the parentheses match?

In most cases they won't. For example, 9 is 1001 in binary, which becomes ())(, where only the first two parentheses match.

But sometimes they will match. For example, 44 is 101100 in binary, which becomes ()(()), where all the left parentheses have a matching right parenthesis.

Write a program or function that takes in a positive base ten integer and prints or returns a truthy value if the binary-parentheses version of the number has all matching parentheses. If it doesn't, print or return a falsy value.

\$\begingroup\$Excellent! Two things that might help: 1) If it's falsy when going up, it's already been falsy going down, so you shouldn't need the first tilde. 2) I believe ~--c is falsy in exactly the same scenario as c--.\$\endgroup\$
– ETHproductionsNov 16 '15 at 15:27

Pyth, 10 bytes

How it works

(implicit) Store the evaluated input in Q.
.BQ Return the binary string representation of Q.
u Reduce w/base case; set G to .BQ and begin a loop:
`T Return str(10) = "10".
cG Split G (looping variable) at occurrences of "10".
s Join the pieces without separators.
Set G to the returned string.
If the value of G changed, repeat the loop.
This will eventually result in either an empty string or a
non-empty string without occurrences of "10".
! Return (and print) the logical NOT of the resulting string.

\$\begingroup\$You can save two bytes by removing the not needed f=. You can also use use +c instead of c|0 to case to an integer. You can also use (+c?d++:d--) which is even shorter\$\endgroup\$
– DowngoatNov 16 '15 at 4:15

\$\begingroup\$@Vɪʜᴀɴ OK. Is there some kind of guide as to when I need to use f=? Because a lot of other JavaScript answers on the site name their functions.\$\endgroup\$
– user81655Nov 16 '15 at 4:19

1

\$\begingroup\$Typically you only need to give the function a name if the challenge requires you to do so. Otherwise it's safe to assume that unnamed functions are fine.\$\endgroup\$
– Alex A.Nov 16 '15 at 4:20

\$\begingroup\$In Firefox, running this for 11, returns true when it should return false\$\endgroup\$
– DowngoatNov 16 '15 at 4:25

2

\$\begingroup\$I don't know javascript, but I attempted to cut a few bytes and it works in chrome: n=>![...n.toString(d=2)].some(c=>(d+=c*2-1)<2)*d==2\$\endgroup\$
– xsotNov 16 '15 at 9:45

Python 2, 45 bytes

f=lambda n,i=1:i*n>0<f(n/2,i+(-1)**n)or n<i<2

A recursive function. Reads binary digits of n from the end, keeping a count i of the current nesting level of the parens. If it falls below 0, reject. When we reach the start, checks whether the count is 0.

Actually, we start the count at i=1 to make it easy to check if it has fallen to 0. The only terminal success case is n==0 and i==1, checked with n<i<2. We force this check to happen if n==0, or if i falls to 0, in which case it automatically fails.

feersum saved two bytes by restructuring the non-recursive cases with inequalities to short-circuit.

CJam, 11 bytes

ri2b"}{"f=~

This is a tad unclean: For parenthifiable numbers, it will print one or more blocks. For non-parenthifiable numbers, it will crash without printing anything to STDOUT. If you try this online in the CJam interpreter, keep in mind that it doesn't distinguish between STDOUT and STDERR.

Since non-empty/empty strings are truthy/falsy in CJam and printed output is always a string, it arguably complies with the rules. At the added cost of 3 more bytes, for a total of 14 bytes, we can actually leaves a truthy or falsy string on the stack that will be printed:

How it works

ri e# Read an integer from STDIN.
2b e# Push the array of its binary digits.
"}{"f= e# Replace 0's with }'s and 1's with {'s.
~ e# Evaluate the resulting string.
e# If the brackets match, this pushes one or more blocks.
e# If the brackets do not match, the interpreter crashes.

CJam, 15 bytes

How it works

ri Read an integer from STDIN.
2b Push the array of its binary digits.
s Cast to string.
_, Push the string's length.
{ }* Do that many times:
As/ Split at occurrences of "10".
s Cast to string to flatten the array of strings.
! Push the logical NOT of the result.

Python, 51 bytes

lambda n:eval("'0b'==bin(n)"+".replace('10','')"*n)

An anonymous function. Evaluates to an expression that looks like

'0b'==bin(n).replace('10','').replace('10','').replace('10','')...

Each replacement removes all 10, which correspond to (). After all replacements have been made, the function returns whether what's left is just the binary prefix 0b. It more than suffices to make n replacements, since a k-digit number takes at most k/2 steps, and its value is most 2**k.

, get value from stdin
; dupe top of stack
2@¡ pop a: push a string containing the binary representation of a (swapping to get order of operands correct)
@ swap top two elements to get original input back on top
`""9u$(Æ` define a function:
"" push empty string
9u$ push "10" (push 9, add 1, stringify)
( rotate stack right by 1
Æ pop a,b,c: push a.replace(b,c) (replace all occurrences of "10" in the binary string with "")
n pop f,a: call f a times
Y pop a: push boolean negation of a (1 if a is falsey else 0)

Shortly after this challenge, @Vɪʜᴀɴ (now known as @Downgoat) helped me implement a recursive-replace feature, like W in the TeaScript answer. This means that this challenge can now be done in just 5 bytes:

Python 2, 60575655535250 49 bytes

n=input()
i=1
while i*n:i+=1|n%-2;n/=2
print i==1

Thanks to xnor for saving two bytes and feersum for bringing the final byte count to 49!

Explanation

The input number, n, is processed from its least significant bit. i is a counter that keeps track of the number of 0's and 1's. Note that it is initialised to 1 to save a byte. The loop will abort before n reaches 0 if the number of 1's exceed the number of 0's (i<=0).

For the parentheses to be balanced, two conditions are required:

The number of 0's and 1's are equal (i.e. i==1)

The number of 1's never exceeds the number of 0's during this process
(i.e the loop doesn't abort prematurely so n==0). Edit: I realised that this condition isn't necessary as i must be non-positive if n!=0 so the previous condition is sufficient.

\$\begingroup\$I like the translation to parentheses. However, if you leave it as 1s and 0s, it's a good bit shorter: function p(x){x=x.toString(2);r=/10/;while(x.search(r)>=0){x=x.replace(r,"")}return!x}\$\endgroup\$
– ETHproductionsNov 16 '15 at 18:36

\$\begingroup\$@ETHproductions Good point! I think I'll leave the other code at the bottom, I really like the algorithm ^_^ Thanks mate!\$\endgroup\$
– Conor O'BrienNov 16 '15 at 18:37

\$\begingroup\$The ES6 version can still be golfed a bunch: x=>([...x=x.toString(2)].map(_=>x=x.replace(/10/,"")),!x) The trick is to move the while loop into a .map, since there are never more '10's in an input than its length.\$\endgroup\$
– ETHproductionsNov 16 '15 at 18:57

\$\begingroup\$No problem :) BTW, another byte can be saved with a trick edc65 uses all the time: x=>[...x=x.toString(2)].map(_=>x=x.replace(/10/,""))&&!x IDK if it can get shorter though.\$\endgroup\$
– ETHproductionsNov 16 '15 at 19:00

PowerShell, 106 Bytes

Not going to win any shortest-length competitions, that's for sure. But hey, at least it's beating Java?

Uses the very long .NET call [convert]::ToString($a,2) to convert our input number to a string representing the binary digits. We then for-loop through that string with 1..$b.length|%{..}. Each loop, if our digit is a 1 (evaluated with %2 rather than -eq1 to save a couple bytes), we increment our counter; else, we decrement it. If we ever reach negative, that means there were more ) than ( encountered so far, so we output 0 and exit. Once we're through the loop, $c is either 0 or some number >0, so we take the logical-not ! of it, which gets output.

This has the quirk of outputting 0 if the parens are mismatched because we have more ), but outputting False if the parens are mismatched because we have more (. Essentially functionally equivalent falsy statements, just interesting. If the parens all match, outputs True.

\$\begingroup\$No, j is an inner variable in the for loop and cannot be referenced outside it.\$\endgroup\$
– GamrCorpsNov 16 '15 at 19:14

\$\begingroup\$You should be able to combine the other way, though: int k=0,j=0;for(... Then you could put the char[] declaration inside the loop initializer to save a semicolon, too.\$\endgroup\$
– GeobitsNov 16 '15 at 19:38

C++, 61 bytes

I think the current C++ answer is wrong: it returns a truthy value for all even numbers, e.g. 4. Disclaimer: I was not able to use the mentioned compiler, so I used g++ 4.8.4. The problem lies in the use of the binary AND operator instead of the logical AND which is used to break early when the number of closing parentheses exceed the number of opening parentheses. This approach could work if true is represented as a word with an all true bit pattern. On my system, and probably most other systems, true is equivalent to 1; only one bit is true. Also, n/=2 is shorter than n>>=1. Here is an improved version as a function:

Your Answer

If this is an answer to a challenge…

…Be sure to follow the challenge specification. However, please refrain from exploiting obvious loopholes. Answers abusing any of the standard loopholes are considered invalid. If you think a specification is unclear or underspecified, comment on the question instead.

…Try to optimize your score. For instance, answers to code-golf challenges should attempt to be as short as possible. You can always include a readable version of the code in addition to the competitive one.
Explanations of your answer make it more interesting to read and are very much encouraged.

…Include a short header which indicates the language(s) of your code and its score, as defined by the challenge.

More generally…

…Please make sure to answer the question and provide sufficient detail.

…Avoid asking for help, clarification or responding to other answers (use comments instead).

Code Golf Stack Exchange is a site for recreational programming competitions, not general programming questions. Challenges must have an objective scoring criterion, and it is highly recommended to first post proposed challenges in the Sandbox.