Introduction
Given a String containing an arithmetic expression, your task is to output a truthy or falsey value based on whether it contains unmatched parentheses.
Input
Your program should take in a String containing an arithmetic expression. It may take input in any way except assuming it to be present in a pre-defined variable. Reading from file, input box, modal dialog box etc. is fine. Taking input as function argument is allowed as well!
Output
Your program should output a truthy or falsey value based on whether the input String contains any unmatched parentheses. It may output in any way except except writing to a variable. Writing to file, screen, console, terminal etc. is allowed. Outputting with function return
is allowed as well!
Rules
For the purpose of this challenge, a parentheses is defined as any one of
[
,{
,(
,)
,}
,]
. A parentheses is said to be unmatched if it does not have any corresponding opening/closing parentheses. For example,[1+3
does contain unmatched parentheses.Ordering of parentheses does not matter in this challenge. So,
]1+3[
does not contain any unmatched parentheses.{[)(}]
doesn't, as well.The input String will only contain following characters :
{
,[
,(
,)
,]
,}
,1
,2
,3
,4
,5
,6
,7
,8
,9
,0
,+
,-
,*
,/
and^
.Your program should output a truthy value if the input String contains an unmatched parentheses.
Your program should output a falsey value if the input String does not contain an unmatched parentheses.
You must specify the truthy and falsey values in your post.
The input String will never be empty.
If the input String does not contain any parentheses, your program should output falsey value.
Standard loopholes apply.
Test Cases
Input -> Output
"{" Truthy
"{{{{}}" Truthy
"{[]}" Falsey
"[]][" Falsey
")()()()(" Falsey
"1+4" Falsey
"{)" Truthy
"([)]" Falsey
"(()" Truthy
"2*{10+4^3+(10+3)" Truthy
"-6+[18-{4*(9-6)}/3]" Falsey
"-6+[18-{4*)9-6](/3}" Falsey
Winning Criterion
This is code-golf, so the shortest code in bytes wins!
Note
I'll be adding a similar challenge but in which order will matter, after some time! Stay Tuned!
17 Answers 17
Python 2, 47 bytes
lambda s:map(s.count,'([{')!=map(s.count,')]}')
Try it online! Test cases from musicman523.
Checks if list of counts for each type of open paren matches that for the corresponding close parens.
The program is one byte longer
q=input().count
print map(q,'([{')!=map(q,')]}')
05AB1E, (削除) 14 (削除ここまで) 10 bytes
žuS2ドルô€ËP_
-4 thanks to Adnan.
1
for truthy, 0
for falsey.
Its main power point is the žu
builtin.
Explanation:
žuS2ドルô€ËP_
žu Push '()<>[]{}'
S Split into individual chars
¢ Count occurrences of each char in the input. For <>, the count will always be 0
2 Push 2
ô Split the array into pieces of that length, corresponding to respective matching brackets
€ Map next command over the chunks
Ë Check if all elements are equal. If equal, it means that the corresponding bracket type is matched. <> will always be matched, since they will never occur in the input, so they'll both always have 0 occurrences
P Take the product of the boolean values. <> won't affect this, since it would always be 1
_ Logically negate, convert 1 to 0 and non-1 (always 0 in this case) to 1
-
4\$\begingroup\$ Who doesn't have a command that pushes
()<>[]{}
? \$\endgroup\$2017年06月03日 18:48:57 +00:00Commented Jun 3, 2017 at 18:48 -
\$\begingroup\$ @cairdcoinheringaahing CJam doesn't, but you can get it with
[{(<>)}]`
. \$\endgroup\$Esolanging Fruit– Esolanging Fruit2017年06月04日 05:57:40 +00:00Commented Jun 4, 2017 at 5:57 -
\$\begingroup\$ @Challenger5 You just correctly ordered the brackets so that the
(<>)
won't affect the stack since it's in a code block, and then the codeblock goes into the list? Well, this challenge doesn't have<>
, so you could just use[{()}]`
or{[()]}`
or even{([])}`
. Oh wait a sec, you can actually use{()}a`
. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年06月04日 06:48:19 +00:00Commented Jun 4, 2017 at 6:48 -
\$\begingroup\$ @EriktheOutgolfer Yeah, I forgot about that. \$\endgroup\$Esolanging Fruit– Esolanging Fruit2017年06月04日 06:52:48 +00:00Commented Jun 4, 2017 at 6:52
-
1\$\begingroup\$ @Arjun They're not handled, since they'll never be in the input. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年06月05日 07:51:19 +00:00Commented Jun 5, 2017 at 7:51
Python 2, 61 bytes
Saved 4 bytes thanks to WheatWizard!
lambda s:any(s.count(i)^s.count(j)for i,j in['{}','[]','()'])
-
\$\begingroup\$ This can be made slightly shorter by ditching
r
. Try it online \$\endgroup\$2017年06月03日 17:54:32 +00:00Commented Jun 3, 2017 at 17:54 -
\$\begingroup\$ Thanks! I changed it to match the two characters into separate variables, removing the indexing and therefore saving 4 more bytes. \$\endgroup\$musicman523– musicman5232017年06月03日 17:58:37 +00:00Commented Jun 3, 2017 at 17:58
Python 3, (削除) 62 (削除ここまで) 61 bytes
Surprisingly pythonic for codegolf.
lambda x:all(x.count(y)-x.count(z)for y,z in("[]","()","{}"))
-1 byte thanks to @musicman523
-
\$\begingroup\$ You can use musicman's trick to make this shorter. TIO \$\endgroup\$2017年06月03日 17:58:52 +00:00Commented Jun 3, 2017 at 17:58
-
1\$\begingroup\$ And now we have the same answers :) Although your post came before my edit, I did come up with it independently \$\endgroup\$musicman523– musicman5232017年06月03日 17:59:12 +00:00Commented Jun 3, 2017 at 17:59
-
\$\begingroup\$ Yeah, I'll leave it as is. \$\endgroup\$L3viathan– L3viathan2017年06月03日 18:00:59 +00:00Commented Jun 3, 2017 at 18:00
-
\$\begingroup\$ You could change
==
to-
and keepall
, then we have the same byte count but different answers \$\endgroup\$musicman523– musicman5232017年06月03日 18:01:44 +00:00Commented Jun 3, 2017 at 18:01 -
\$\begingroup\$ @musicman523 Alright then! \$\endgroup\$L3viathan– L3viathan2017年06月03日 18:04:17 +00:00Commented Jun 3, 2017 at 18:04
MATL, 15 bytes
!'[](){}'=sHeda
This outputs 1
if unmatched, 0
if matched.
Explanation
! % Implicitly input string. Tranpose into vertical vector of chars
'[](){}' % Push this string
= % Compare for equalty, with broadcast
s % Sum of each column. This gives the count of each char of '[](){}'
He % Reshape as a two-row column (in column-major order)
d % Difference of the two entries of each column
a % Any: gives true (1) if some entry is nonzero, false (0) otherwise
% Implicitly display
Javascript, 71 bytes:
x=>['()','[]','{}'].some(a=>x.split(a[0]).length!=x.split(a[1]).length)
Ruby, 58+1 = 59 bytes
+1 byte for the -n
flag.
f=->c{$_.count c}
p %w"() [] {}".any?{|s|f[s[0]]!=f[s[1]]}
Javascript 57 bytes
x=>(g=z=>x.split(z).length,g`(`-g`)`|g`[`-g`]`|g`{`-g`}`)
Starting from asgallant's solution.
Matching returns 0. Non-matching returns non-zero.
Python 2, 85 bytes
I can definitely golf this using subtraction instead but I'm running out of time. D:
lambda s,c=str.count:(c(s,'(')!=c(s,')'))or(c(s,'{')!=c(s,'}'))or(c(s,'[')!=c(s,']'))
-
\$\begingroup\$ All instances of
!=
can be-
. \$\endgroup\$CalculatorFeline– CalculatorFeline2017年06月06日 21:52:21 +00:00Commented Jun 6, 2017 at 21:52 -
\$\begingroup\$ This answer has already been out-golfed by a far better answer. Hence, I'd rather not try to golf this. \$\endgroup\$totallyhuman– totallyhuman2017年06月06日 21:56:59 +00:00Commented Jun 6, 2017 at 21:56
PowerShell, (削除) 95 (削除ここまで) 86 bytes
param($s)$h=@{};[char[]]$s|%{$h["$_"]++};$h.'['-$h.']'-or$h.'('-$h.')'-or$h.'{'-$h.'}'
Previous version
param($s)switch([char[]]$s){'('{$k++}')'{$k--}'['{$l++}']'{$l--}'{'{$m++}'}'{$m--}}$k-or$l-or$m
C#, 87 bytes
using System.Linq;s=>s.Count(c=>c=='['|c=='{'|c=='(')==s.Count(c=>c==']'|c=='}'|c==')')
Pretty self explanatory, just test to see if the of left parenthesis equals the count of right parenthesis.
-
\$\begingroup\$ Please check on
{)
. \$\endgroup\$CalculatorFeline– CalculatorFeline2017年06月06日 21:54:59 +00:00Commented Jun 6, 2017 at 21:54
PHP>7.1, 124 Bytes
$t=!!$p=preg_replace("#[\d+/*^-]#","",$argn);for(;$p;$p=substr($p,1,-1))$t*=chr(($o=ord($p[0]))%5?$o+2:$o+1)==$p[-1];echo$t;
Instead of #[\d+/*^-]
you can use [^]{()}[]
or [^\p{Pe}\p{Ps}]
IntlChar::charMirror IntlChar::charMirror($p[0])==$p[-1]
instead of chr(($o=ord($p[0]))%5?$o+2:$o+1)==$p[-1]
checks not if the char is an openining or closing punctation so we can not use it without additional check &$p[0]<$p[-1]
+8 Bytes
PHP, 151 bytes
A full Regex Solution
for($c=$t=!!$p=($r=preg_replace)("#[^]{()}[]#","",$argn);$p&&$c;)$p=$r(["#^{(.*)}$#","#^\[(.*)]$#","#^\((.*)\)$#"],[$a="1ドル",$a,$a],$p,1,$c);echo$t&!$p;
Visual Basic.Net, (削除) 218 (削除ここまで) 192 Bytes
function t(m as string,v as string)
return Len(m)-Len(m.Replace(v,""))
end function
function b(q as String)
return not(t(q,"{")=t(q,"}")and t(q,"[")=t(q,"]")and t(q,"(")=t(q,")"))
end function
-
\$\begingroup\$ "around 218 bytes" I count 217. Also,
if (expr) then return false else return true
can bereturn not (expr)
. \$\endgroup\$CalculatorFeline– CalculatorFeline2017年06月06日 21:54:25 +00:00Commented Jun 6, 2017 at 21:54 -
\$\begingroup\$ "around 218 bytes" I count 192. Do you have a trailing newline? \$\endgroup\$CalculatorFeline– CalculatorFeline2017年06月06日 21:59:22 +00:00Commented Jun 6, 2017 at 21:59
-
\$\begingroup\$ I dont know how to put line through 218 \$\endgroup\$polyglotrealIknow– polyglotrealIknow2017年06月06日 22:00:36 +00:00Commented Jun 6, 2017 at 22:00
-
\$\begingroup\$
<s>218</s>
works. \$\endgroup\$CalculatorFeline– CalculatorFeline2017年06月06日 22:02:02 +00:00Commented Jun 6, 2017 at 22:02 -
\$\begingroup\$ well I don't have trailing newline \$\endgroup\$polyglotrealIknow– polyglotrealIknow2017年06月06日 22:09:13 +00:00Commented Jun 6, 2017 at 22:09
Clojure, 65 bytes
#(let[f(frequencies %)](some not(map =(map f"[{(")(map f"]})"))))
So long keywords :/ Returns nil
for falsy and true
for truthy.
Retina, 26 bytes
O`.
+`\(\)|\[]|{}
[^*-9^]
Explanation
O`.
Sort all characters so that corresponding brackets are adjacent (since neither \
nor |
can appear in the input).
+`\(\)|\[]|{}
Repeatedly remove pairs of matching brackets.
[^*-9^]
Try to match any remaining brackets (the regex matches anything that isn't a ^
or in the ASCII range from *
to 9
which, among the valid input characters, are only the 6 brackets). If we find any, that means that there was an unmatched one. The result will be a positive integer if the input was unbalanced, 0
otherwise.
-
\$\begingroup\$
{{{{}}
is matched? Your code return0
on that input. \$\endgroup\$user202729– user2027292017年06月07日 14:20:07 +00:00Commented Jun 7, 2017 at 14:20 -
\$\begingroup\$ @user202729 Thanks, it should be fixed now (luckily at the same byte count). \$\endgroup\$Martin Ender– Martin Ender2017年06月07日 15:23:46 +00:00Commented Jun 7, 2017 at 15:23
Javascript, (削除) 149 (削除ここまで) 140 bytes
New solution incorporates bitwise operators (Thanks, arjun) and calculates if they are not equal, and uses or instead of and.
function f(x){return x.split("(").length!=x.split(")").length|x.split("{").length!=x.split("}").lengt|x.split("[").length!=x.split("]").length}
I don't yet have a snippet for this, so I'm not sure it works yet.
OLD SOLUTION:
function f(x){return !(x.split("(").length==x.split(")").length&&x.split("{").length==x.split("}").length&&x.split("[").length==x.split("]").length)}
Checks if there are the same amount of one bracket and another, and then returns the opposite.
function f(x){return !(x.split("(").length==x.split(")").length&&x.split("{").length==x.split("}").length&&x.split("[").length==x.split("]").length)}
/*"{" Truthy
"{[]}" Falsey
"[]][" Falsey
")()()()(" Falsey
"1+4" Falsey
"{)" Truthy
"([)]" Falsey
"2*{10+4^3+(10+3)" Truthy
"-6+[18-{4*(9-6)}/3]" Falsey
"-6+[18-{4*)9-6](/3}" Falsey*/
console.log(f("{"));
console.log(f("{[]}"));
console.log(f("[]]["));
console.log(f(")()()()("));
console.log(f("1+4"));
console.log(f("{)"));
console.log(f("([)]"));
console.log(f("2*{10+4^3+(10+3)"));
console.log(f("-6+[18-{4*(9-6)}/3]"));
console.log(f("-6+[18-{4*)9-6](/3}"));
-
\$\begingroup\$ I can save 3 bytes by making every == into a != And changing && to || but I'm on mobile \$\endgroup\$willowis.cool– willowis.cool2017年06月05日 18:55:58 +00:00Commented Jun 5, 2017 at 18:55
-
\$\begingroup\$ I think, bitwise operators instead of logical ones will do fine. Like
&
instead of&&
and|
instead of||
. \$\endgroup\$Arjun– Arjun2017年06月07日 06:54:26 +00:00Commented Jun 7, 2017 at 6:54 -
\$\begingroup\$ You can remove the outermost paren after
return !
. \$\endgroup\$Arjun– Arjun2017年06月07日 06:55:43 +00:00Commented Jun 7, 2017 at 6:55 -
\$\begingroup\$ Do you even need a space after
return
? \$\endgroup\$Adalynn– Adalynn2017年06月07日 15:32:38 +00:00Commented Jun 7, 2017 at 15:32 -
\$\begingroup\$ I think you need that space otherwise JavaScript will count it as rerurnx and throw an error \$\endgroup\$willowis.cool– willowis.cool2017年06月07日 19:43:04 +00:00Commented Jun 7, 2017 at 19:43
Explore related questions
See similar questions with these tags.
][
or([)]
would be valid in the other challenge but are valid here. \$\endgroup\$