[Question]
  [
Every phone needs a calculator app. Because of the limited screen real estate, the developer of mine has decided to save some buttons. Instead of having two dedicated bracket buttons - one for open `(` and one for close `)` - there is just a single bracket button `()`. It looks something like this:
[![My phone's calculator app](https://i.stack.imgur.com/b9XvQl.jpg)](https://i.stack.imgur.com/b9XvQl.jpg)
When the button is pressed, it places a bracket. Based on the input given so far, it predicts whether the bracket should be open `(` or close `)`.
By trial and error, I have found the button to follow these rules:
* If there are no unmatched brackets, the next bracket will **always** be open `(`.
* Else, if the last character is a numeral `0123456789` or close `)` bracket, the next bracket will be close `)`.
* Else, if the last character is an operator `+-*/` or open `(` bracket, the next bracket will be open `(`.
## The challenge
Based on the given input and the rules mentioned above, predict whether the button places an open `(` or close `)` bracket.
## Input
Either a string, an array of characters, or anything equivalent. The input will **only** contain the following characters\*: `0123456789+-*/()`
## Output
An open `(` or close `)` bracket **or** any two consistent values representing them.
## Test cases
```
""                  -> "("
"(1+"               -> "("
"(1+(2/3"           -> ")"
"(1+(2/3)"          -> ")"
"(1+(2/3))-8"       -> "("
"(1+(2/3))-8*("     -> "("
"(1+(2/3))-8*((5"   -> ")"
"(1+(2/3))-8*((5)"  -> ")"
"(1+(2/3))-8*((5))" -> "("
```
## Scoring
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest answer in each language wins.
### Note
\* The actual calculator also includes the symbols `.%`, but you don't need to care about those.
  
[Answer]
# [JavaScript (Node.js v11.6.0)](https://nodejs.org), 48 bytes
```
a=>/k/.test(eval("try{eval(a+')')}catch(e){e}"))
```
[Try it online!](https://tio.run/##jc69CsIwFMXx3acIZ@m9ljaoCC71XUJM/QqNNKEgpc8erYtQEe6ZzvAb/jczmGj76yNVXTi53DbZNEd913VyMZEbjCek/jl@nikLLniyJtkLOR7dBOZsQxeDd7UPZ2oJUMsxK60VCKsFpU0JOaWt3uGH8j/KkFOuDpAFzHRNkFPaQxYw03ezmDK@AfkF "JavaScript (Node.js) – Try It Online")
We try to append a character `')'` to the end of expression and `eval` it. Node v11.6.0 (as current version on TIO) may:
* Calculate the expression if the expression is valid
	+ The calculate result may only contain characters `/[0-9INafinty]/`
* Report error `SyntaxError: Unexpected token )` if the `)` should not be there
* Report error `SyntaxError: Unexpected end of input` if the `)` is valid there
So we just need to check if the result contains letter `"k"`.
[Answer]
# [C (clang)](http://clang.llvm.org/) on Linux, ~~82~~ ~~79~~ ~~66~~ 62 bytes
```
c;f(*x){for(c=0;*x;++x)*x&22?:*x&1?--c:++c;c*=*--x&16|*x==41;}
```
[Try it online!](https://tio.run/##bZBLTsMwEIb3OcXIVZE9riEJFKEa0wtwg6aLyEnaSMFFTooshZw9OIaiUjqLeXzjx/yjhW5ysxtHLSuKjvXVwVKtYolOcu4Yups0Xa98SNZC6BXnWmpUKIQnj5/olHpI5DDOaqObY1E@t11RH273L1FUmw7e8trQKcntTi9A73ML6POPzZZBH4G3qYtd2XbtZgsKenglZOEdTfgp0vTu/jxnfwomni5rpP8JXV5j7Cr8oZc24RgGGeb2i4JJGiJM0/vRgwj5LUaGivOTynCDhhaTv@Td@gcqSuYFZGTetBnJjP/Db@r85BC8LbujNRDLaBi/AA "C (clang) – Try It Online")
Expects a nul-terminated ASCII wide string (4 bytes per character). Returns false (zero) for open bracket and true (nonzero) for close bracket.
* Thank you to @AZTECCO for golfing off 13 bytes!
* And thank you to @jdt for golfing off 4 more bytes. (This required switching to clang; the original answer was for gcc.)
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~18~~ 16 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
„()S¢Ëžh')«Iθå≠~
```
-2 bytes by outputting `1` for `(` and `0` for `)`.
[Try it online](https://tio.run/##ATAAz/9vc2FiaWX//@KAnigpU8Kiw4vFvmgnKcKrSc64w6XiiaB@//8oMSsoMi8zKSktOCo) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfeX/Rw3zNDSDDy063H10X4a65qHVled2HF76qHNB3X@d/9FKSjpKGobaEFLDSN8YwdJEYmrqWqDytDTQ@RqmmCKaWIQ0lWIB).
**Explanation:**
```
„()        # Push string "()"
   S       # Convert it to a character-list: ["(",")"]
    ¢      # Count the "(" and ")" in the (implicit) input-string
     Ë     # Check whether both are the same
žh         # Push builtin "0123456789"
  ')«     '# Append a ")"
     Iθ    # Push the last character of the input-string
       å≠  # Check that it's NOT in the string "0123456789)"
~          # Bitwise-OR to check if at least one is truthy
           # (after which this is output implicitly as result)
```
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 16 bytes
```
‛()$vO≈9ʀ\)J?tc∨
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=&code=%E2%80%9B%28%29%24vO%E2%89%889%CA%80%5C%29J%3Ftc%E2%88%A8&inputs=%27%281%2B%27&header=&footer=)
0 for `(` and 1 for `)`
[Answer]
# [Python 2](https://docs.python.org/2/), 48 bytes
```
lambda L:"0">cmp(*map(L.count,"()"))*L[-1:]!=")"
```
[Try it online!](https://tio.run/##ddBNC4JAEAbg@/6K7b04Y9onQQjrL/DorTzYh7Sgu0ttQb/elIigdG7DM7zDjHv6izWrtlL7ti6bw6mUWYIF0mPjKGxKR9nsaO/GRyAGc5jt4mVSTBQYba6CIADkX8WpBEGAllOME63ma/wQf4kxThxvMRzYU0gYJ9pgOLCnfucYdfYO7I6e3VytPWFvwKKyV@mlNjJPhNSRVf3bzo@yjvxn7h3KQrqrNl3PhF1FmgulLIv2BQ "Python 2 – Try It Online")
Based on @wasif's Python 3 answer; shortened using `cmp` which is not available in Python 3.
True for "("
False for ")"
[Answer]
# [Perl 5](https://www.perl.org/) -nMv5.10, 23 bytes
```
say!/[\d)]$/||eval&&!$@
```
[Try it online!](https://tio.run/##K0gtyjH9/784sVJRPzomRTNWRb@mJrUsMUdNTVHF4f9/Lg1DbRDWMNI3htGacIamrgUyW0sDladhis7XxBDQ/JdfUJKZn1f8Xzfvv66vqZ6hgZ4BAA "Perl 5 – Try It Online")
Prints true/1 for `(` and false/empty string for `)`.
And for eight extra bytes we can print `(` and `)` like this: [Try it online](https://tio.run/##K0gtyjH9/784sVJRPzomRTNWRb@mJrUsMUdNTVHFwV5dQ91KXVP9/38uDUNtENYw0jeG0ZpwhqauBTJbSwOVp2GKztfEEND8l19QkpmfV/xfN@@/rq@pnqGBngEA "Perl 5 – Try It Online") 31 bytes. The `eval&&!$@` checks if the input expression have balancing parentheses by using the Perl compiler to check if it compiles.
[Answer]
# [GNU AWK](https://www.gnu.org/software/gawk/manual/gawk.html), 75 bytes
```
BEGIN{RS=".|"}RT~/\(/{++n}RT~/\)/{--n}END{print n?RT~/[\)0-9]/?")":"(":"("}
```
[Try it online!](https://tio.run/##SyzP/v/fydXd0686KNhWSa9GqTYopE4/RkO/Wls7D8LW1K/W1c2rdfVzqS4oyswrUcizB4lHx2ga6FrG6tsraSpZKWmAce3//wA "AWK – Try It Online")
```
BEGIN{RS=".|"}
```
Starts reading the input one character at a time, which are stored in the `RT` variable, by the way.
```
RT~/\(/{++n}
RT~/\)/{--n}
```
If the character is a `(`, increments `n` by one. If it is `)`, decrements `n` by one.
```
END{print 
          n?
            RT~/[\)0-9]/?
                         ")"
                        :"("
           :"("
   }
```
If `n` equals zero, i.e., there are as many `(` as `)`, prints `(`. If `n` is different from zero, evaluates the last character (registered in `RT`). If it is a number or `)`, prints a `)`, otherwise, prints `(`.
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), 30 bytes
```
{(^"(*+-/"?*|x)>~+/-/x=/:"()"}
```
[Try it online!](https://ngn.codeberg.page/k#eJx1z9EKgjAUxvH7PcU4dHGmjGkRxEb2IGLYjRAFgXgxMX323BRTt53bH3yHfyU7vANGMRdwi76aZUMsuNBXIQEZ9IQ0sjvk7VDLilKqVfl5KSyrx/OttGpVzYqeNDmAos4lhRFMYwcXwaM4bTRdC1vTVhi/LJjsJcLZPIJna86aEfvPL4bGNSIIgFvKMwoIxLaGycbuiP2JQZhMrn9w7g3TGOwfnIrDNNo0+AOtr2Ho)
Returns `0` for `"("` and `1` for `")"`.
* `~+/-/x=/:"()"` determine whether or not the input contains a balanced number of parenthesis, i.e. that the number of `"("`s minus the number of `")"`s is 0
* `(^"(*+-/"?*|x)` determine if the last character is one that should be followed by a `"("` (i.e. one of `"+-*/("`) or not
* `(...)>...` use `>` as material nonimplication (i.e. only return a truthy value if the left side is truthy and the right side isn't)
[Answer]
# JavaScript (ES6), ~~52~~ 51 bytes
Expects an array of characters. Returns `0` for `(`, or `1` for `)`.
```
a=>a.map(c=>q+=-(d=c>-1,C=c==')')|c<')',q=0)|q&&d|C
```
[Try it online!](https://tio.run/##lc@xDoIwEMbx3acgN8Cd0FY0Jg5eFx7DODQFDAYpiHHi3StMJmpMesu3/Ib/Xc3TjPbe9A/RubLyNXvD2sib6dGyHlIWWLLVIs8KtswJJTTZ4zzZwBuahjgup8Jb142urWTrLljjSUoJEH3emShSKgKE1Q@PeQqBHrdqB9@e/nmCQE/iAAE9i18jBHrcQ0DP4uc/wjzBu8e/AA "JavaScript (Node.js) – Try It Online")
### Commented
```
a =>               // a[] = input array of characters
a.map(c =>         // for each character c in a[]:
  q +=             //   update q
    -(             //   which keeps track of the balance of parentheses
      d = c > -1,  //   d = digit flag
      C = c == ')' //   C = closing parenthesis flag
    )              //   decrement q if C is set
    | c < ')',     //   or increment it if c is '('
  q = 0            //   start with q = 0
) |                // end of map()
q &&               // return 1 if q is not 0 (unbalanced parentheses)
d                  // and the last character was either a digit
  | C              // or a closing parenthesis
```
[Answer]
# [Zsh](https://www.zsh.org/), 39 bytes
Exits truthy if a `(` should be inserted, falsy if a `)` should be inserted.
```
eval ${(s..)1//[^()]/;}||${(M)1%[0-9)]}
```
[Try it online!](https://tio.run/##fc3dSgMxEAXg@zzFYVghY03XtQiVRfEFvPC6VGibWTcQNtKsP9jus68JCIJ2zd3kO3PmM7ZjlD689JCPXjor9tmHrWo061HeNh7FQcf5nKuyXD1pXpf1cDymvweuzlaX5obXw8hKvbfOC/aysTB7eNdJDRuUAlI7jAGlnftHLg63GYeBErkGDYqqRt9Kl2ZAdm0AxTa8eoutoFhcwEXonBYf5b8Q51DjlLKhk5EIf565A6Uq0tWMpklflQv6RfxDTNPEZkmnCzOda5omfU2nCzPlm1OU7LvwCw "Zsh – Try It Online")
The `eval` handles the matching (getting rid of non-`()` characters, and spawning nested subshells with spaces and `;`s to prevent `()()` or `(( ))` from erroring).
The `${(M)1%[0-9)]}` simply tries to run the last character of the input as a program if it is in `0123456789)`, failing. `||` brings the whole logic together.
[Answer]
# TI-Basic, 71 bytes
```
Prompt Str1
For(I,1,length(Str1
sub(Str1,I,1→Str2
O+(Ans="(→O
C+(Str2=")→C
End
0
If O≠C
not(inString("+-*/(",sub(Str1,length(Str1),1
Ans
```
Output is stored in `Ans` and displayed. Outputs `0` for `(` and `1` for `)`.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~15~~ 14 bytes
```
ċⱮØ(Iɓ”)ØD;faƒ
```
[Try it online!](https://tio.run/##y0rNyan8//9I96ON6w7P0PA8OflRw1zNwzNcrNMSj036f7hdM/L/fyUlHSUNQ20IqWGkb4xgaSIxNXUtUHlaGuh8DVNMEU0sQppKAA "Jelly – Try It Online")
*-1 because I actually looked at other solutions and remembered `ċ` exists*
Returns falsy (empty list) for open or truthy (nonempty list) for close. Took a hell of a lot of permuting to get here from `=€Ø(ISaṪe”)ṭØD¤Ɗ`.
```
        ØD;       Concatenate "0123456789" and
      ”)          a closing parenthesis.
           f      Keep only its elements which are also elements of
     ɓ      aƒ    the input reduced LtR by logical AND starting with:
ċⱮØ(              Count the opening and closing parentheses in the input,
    I             and subtract the opens from the closes.
```
[Answer]
# [Haskell](https://www.haskell.org/), 64 bytes
```
o i=elem(last i)"+-*/("||let[o,c]=[[1|c<-i,c==p]|p<-"()"]in o==c
```
[Try it online!](https://tio.run/##BcFBCoAgEADAr8jSYa0krGv7EvEgIrS0qZRH/24zV/juJDJGUUxJ0oMSvqZYw2LmDaF3Sc2VNXpyzvZ4Gl4jUfW9ngZQg@esClEcT@BM9eXcpqIA7YL7dsD4AQ "Haskell – Try It Online")
[Answer]
# C# (8.0), ~~76~~ ~~68~~ 64 bytes
*-3 bytes thanks to [ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat)  
-1 byte thanks to [Aaroneous Miller](https://codegolf.stackexchange.com/users/101522/aaroneous-miller)*
```
bool p(char[]i)=>i.Sum(x=>x<42?x*2-81:0)==0||i[^1]<48&i[^1]!=41;
```
[Try it online!](https://tio.run/##bY5RS4RAFEaf119xGyLv3dTUDGTdcYl97SEq6ME1MJvWgc1ZZiYwXH@7RUEh7cvHOefpq41fGzmOz0rtYI91U@milMRzGdy/v2HH826ZxKtuHvtptAiJ8/BwkMVTVC6T9OwbTngSZaOxWrbbogQrjF1XRhjg0Dszxjz4WozOfwHji8uJ0NTIT5k39Tn@L3h1rNHRSMwZMudVaVHVDf58BQOy/btLzmytWqN2InjU0oob2QpkfTiAn0MfDcw7ZRvWm2HDWHBbvdzJbWMxDgm8PZrgQV1rXX0gEazARXfhkkuZM34C "C# (Visual C# Interactive Compiler) – Try It Online")  
Takes not-null (but it might be empty) array of characters and outputs `true` for `(` and `false` for `)`.
Ungolfed:
```
bool p(char[] input){
   int sum = input.Where(x=>x<42)  // take only brackets
       .Select(x=>x*2-81)          // replace '(' with -1 and ')' with 1
       .Sum();                     // sum them 
   if(sum == 0)       // if sum is 0, brackets are balanced
       return true;
   // when left condition in || operator is true the right one isn't checked
   // this is beneficial for us because it prevents from taking last element
   // of empty array - empty input will always have balanced brackets
   char lastChar = i[^1];  // takes last character (this notation requires C# 8.0)
   
   return            // return true (opening bracket) IF:
      lastChar < 48  // last char is '/','*','-','+','(' or ')' 
      &&             // AND
      lastChar != 41;// last char isn't ')'
}
```
[Answer]
## php 4 (83 chars)
Edited because the initial 67 chars answer was not a function, it was a single imperative line :
Using a traditional function allowing to call *f($input)*, so the answer is printed to stdout :
```
function f($a){$s=count_chars($a);echo$s[41]-$s[40]&&$a!=chop($a,')0..9')?')':'(';}
```
## php 7.4 (73 chars)
Using an arrow function allowing to call *$g($input)*, the answer is returned by *$g* :
```
$g=fn($a)=>$a!=chop($a,')0..9')&&($a=count_chars($a))[41]-$a[40]?')':'(';
```
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 18 bytes
```
∨⁼№θ(№θ)№(*+-/§θ±¹
```
[Try it online!](https://tio.run/##S85ILErOT8z5/z@gKDOvRMO/SMO1sDQxp1jDOb8UyC/UUVDSUNLUUUBwNZU04XwlDS1tXX0lHQXHEs@8lNQKkAK/1PTEklQNQ00QsP7/X8NQ@79uWQ4A "Charcoal – Try It Online") Link is to verbose version of code. Outputs `-` for `(`, nothing for `)`. Pretty output can be obtained by prefixing `§)(` (equivalent to `AtIndex(")(", ...)`. Explanation: Port of @wasif's Python answer.
```
  №                 Count of
    (               Literal `(`
   θ                In input string
 ⁼                  Is equal to
     №              Count of
       )            Literal `)`
      θ             In input string
∨                   Logical Or
        №           Count of
              §θ±¹  Last character of input string
         (*+-/      In literal `(*+-/`
                    Implicitly print
```
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 39 bytes
```
(?>(\()|(?<-1>\))|.)*$(?<-1>(?<=[\d)]))
```
[Try it online!](https://tio.run/##K0otycxL/K@q4Z7wX8PeTiNGQ7NGw95G19AuRlOzRk9TSwXCA5K20TEpmrGamv81ueI07BWB8npaXBr/uTQMtUFYw0jfGEZrwhmauhbIbC0NVJ6GKTpfE0NAEwA "Retina 0.8.2 – Try It Online") Outputs `0` for `(` or `1` for `)`, but link is to test suite that maps the results for you. Explanation:
```
(?>(\()|(?<-1>\))|.)*$
```
Atomically count the `(`s and `)`s. (It needs to be atomic otherwise the `.` messes up the count of `)`s, but it's still golfier than `[^()]`.)
```
(?<-1>(?<=[\d)]))
```
Test whether there is an unclosed `(` and the last character is a digit or a `)`.
[Answer]
# [Flex](https://github.com/westes/flex), ~~86~~ 85 bytes
```
%{
p;l;
%}
%%
[(] l=!++p;
[)] p-=l=1;
[0-9] l=1;
[-+*/] l=0;
\n putchar(!!p*l+40);
%%   
```
To run this code, copy the above into a file named `calc.l` and run the following (on linux/bash):
```
flex calc.l
gcc lex.yy.c -o calc -lfl
for t in "" "(1+" "(1+(2/3" "(1+(2/3)" "(1+(2/3))-8" "(1+(2/3))-8*(" "(1+(2/3))-8*((5" "(1+(2/3))-8*((5)" "(1+(2/3))-8*((5))"; do  
    echo -n "\"$t\" -> "
    echo $t | ./calc
    echo
done  
```
and it will output either `(` or `)` to `stdout` for each test string.
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 23 bytes
```
k(↔k(øo[tkd\(+$ck($i|\(
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=&code=k%28%E2%86%94k%28%C3%B8o%5Btkd%5C%28%2B%24ck%28%24i%7C%5C%28&inputs=%27%281%2B%282%2F%27&header=&footer=)
```
k(↔                     # When you remove all but `()` from the input
   k(øo                 # Then remove that until there is no change
       [                # Is there nothing left?
                     \( # If so, opening bracket
                    |   # Else...
        t               # Is the last character of the input...
              $c        # Contained in...
         kd\(+          # Digits + `(`?
                k($i    # Index that into `()`
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~47~~ 43 bytes
```
->e{!!e[/[\d)]$/]&&e.count(?()>e.count(?))}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1y61WlExNVo/OiZFM1ZFP1ZNLVUvOb80r0TDXkPTDs7W1Kz9X6CQFq2kFGuvpKlkpaShpKCsgA507RSAElxghRqG2rjVoinUMNI3xq4YpFATVaEm8So1dS2wKMZiOUillgaGWpwqNUzR1OKwHaQSzb34VKIqhdj@HwA "Ruby – Try It Online")
Outputs *True* for `)`, *False* for `(`.
* Thanks to @Dingus for the insights and 4 Bytes saved
To choose `)` two conditions must hold:
`!!e[/[\d)]$/]` # match($ at the end) the set of characters [numbers, ')'].   
And double negate it to transform *nil*(no match) to *false* else *true*
`e.count(?()>e.count(?))` # open brackets can be equal if balanced, else more than closed ones in which case the second condition is met.
[Answer]
# PHP (8.0), 110 bytes
```
<?php
$a=$argv[1];
$b=ord($a[-1]??'');
die($b>=47||$b==41&&substr_count($a,'(')>substr_count($a,')')?')':'(');
```
[Try it online!](https://tio.run/##ZYpBDoIwEADvfceG3VWJqWI01tKHEGJaIeJFmgKe@Ptaz17mMDNxiCI3F4eowFvw6flpdGsUBDumjsA3pW6dQ2SjuldPEGpbndc1d1vpopiWMM3p/hiX95zvHRJy/ScZ2WVcf9WICOktHfZH5vKyITrxFw "PHP – Try It Online")
Ungolfed:
```
<?php
$a = $argv[1];
// Get the binary value of the first byte of the last character
$lastCharAsciiCode = ord($a[-1] ?? '');
// If the last character in the string is either 0-9 (47-57) OR Closing parenthesis (41)
if ($lastCharAsciiCode >= 47 || $lastCharAsciiCode == 41) {
    // If we have more opening parenthesis than closing, return closing.
    if (substr_count($a,'(') > substr_count($a,')')) {
        die(')');
    }
}
// Return opening by default
die('(');
```
[Answer]
# [R](https://www.r-project.org/), 57 bytes
```
function(x)sum((x=="(")-(x==")"))&&grepl("[)0-9]",rev(x))
```
[Try it online!](https://tio.run/##pdBNC4JAEAbge79imUBmSimLoA4GHerUqY@TiIRsJdgqu2v47027aRqlwxzmMDzDOzIXPNN@cpFc6DtXofKLDqJYcSe/piLQYSwwI5U@EDPHAQSy3gMBkWHcJE8iBJem1soDU/JnsUztKCotVRKFGgFMAHJd2/OIDVm9rDUrbjGH7Tb743bwC4j2@IvZDcTZZN6CliCV4Olw/sujZrC7R9aygeweuARH@EH2BXFRI3slLr3aJ/t7VbAaOH8B "R – Try It Online")
Input is an array of characters; outputs `TRUE` if next parenthesis is close (`)`), `FALSE` otherwise.
[Answer]
# [Rust](https://www.rust-lang.org/), ~~107~~ 104 bytes
```
|s:&str|(|(n,x)|n==0||x)(s.chars().fold((0,true),|v,c|(v.0+match c{'('=>1,')'=>-1,_=>0},c<'0'&&c!=')')))
```
[Try it online!](https://tio.run/##jVLRbpswFH3nK278EK5XhySrqk2k5GHT3qf1AyLkmAaVGIYvbaTAt2fXhDRVV6T6ARsf33OOz3XdODo1zoCjbRznZRz/aLI/Jt2ugszCPs0tSjhCYQiy5NS6eOqobrFFqw6ytUmyaNuDRBfpXVo7lFFWFlvEhaK6MVK1z0q3@BwtbvYp6R3oY4hhsl6qUPI0W6pNsl50St@Hi3A61ZOE96WUJ4BVAJCVNRS5NZDbqz9eeFNRUeonPzHuvEc@DzCfgzcPZBzplK@V1eWey6uGetzfA/tfBeZQGU1mKyGBis2bTQ/g1FNGjX2p0wqlXPWFVZ1bmqA4xvfLbx3M1iDUmZcPXKR/HYxuiEUbqykv7atkbVxTEOtkOH1f9NszDyeuUoU9i911cOxY6oyzZDYsfZCdKZw5cmTd4JLpfu6MfoL0kTvn6DWHHk2dMzVtzN8JjtC8CcUTdkEX@GfwNh0fTgz@FUifAj4Q231Uvv2XJvgb7xuC3N@4D9NVRU4o@tgGq9h//cgpsuZA3MtL5hFz7odp0z8cbnEoQt4pN@WLNVuU6hP1lzdpaYfLK9xXyqA7CQH/DW8RRSBweSPGIfw6vxXvIHmFpBiH5Oy7@JjQQ19QjEN4Jz4m9JDXHIOkGAj/AQ "Rust – Try It Online")
`true` for `(` and `false` for `)`
## Ungolfed
```
|s: &str| {
    // Iterate over all chars, folding from left
    let (paren_counter, ends_with_op_or_open) = s.chars().fold(
        (0, true), // Initial value for fold
        |(n,_), character| (
            // Increment for opening braces and decrement for closing ones
            n + match character { '(' => 1, ')' => -1, _ => 0 },
            // true for +-*/( but not for 0123456789)
            character < '0' && character != ')'
        )
    );
    // Return true if parentheses are balanced or the string ends
    // with an operator or open parenthesis, false otherwise
    paren_counter == 0 || ends_with_op_or_open
}
```
[Answer]
# Javascript, 90 chars
```
s=>s.replace(/.*?([\d)])?$/,(m,c)=>")("[s.replace(/[()]/g,m=>t+=m=='('||-1,t=0),+!(t&&c)])
```
## Test:
```
f=s=>s.replace(/.*?([\d)])?$/,(m,c)=>")("[s.replace(/[()]/g,m=>t+=m=='('||-1,t=0),+!(t&&c)])
console.log(`
""                  -> "("
"(1+"               -> "("
"(1+(2/3"           -> ")"
"(1+(2/3)"          -> ")"
"(1+(2/3))-8"       -> "("
"(1+(2/3))-8*("     -> "("
"(1+(2/3))-8*((5"   -> ")"
"(1+(2/3))-8*((5)"  -> ")"
"(1+(2/3))-8*((5))" -> "("
`.split`
`.filter(x=>x).map(x=>x.match(/"(.*)".*"(.)"/)).map(([,x,r])=>f(x)==r).every(x=>x))
```
[Answer]
# [brainfuck](https://github.com/TryItOnline/brainfuck), 73 bytes
```
,[+>-->[+]+[->+[--->]<<<]<[->>+<<]>>>[->>-<<],]<[,>>]->[+>[>]--<<<++<+]>.
```
[Try it online!](https://tio.run/##FYpBCoBADAO/s0u2XryWfKT0oIIgggfB99fsIWQmZH@36zm/464aAZoxkAijIkl3T5cSApITTTi0DjLnn6HW6IAjuVS1hrX3Hw "brainfuck – Try It Online")
Outputs truthy for `)` and falsy for `(`. Note that this will fail if there are 256 unmatched `(`.
[Version which outputs '(' or ')'](https://tio.run/##HYyxCoBADEN3v@QkVxcnoeRHSgcVBBEcBL//zFkITUL7tmc97@Pdr9ZqgGYMJMIoKaS7pysSMiS7NdmqtpLZ7xnaKh1wJIehM7rcLPSIf1JwHcWPqmJNrZWCecTyAQ "brainfuck – Try It Online") (not particularly golfed)
**Explanation:**
```
,[                                           ,]                               loop until end of input
  +>-->[+]+[->+[--->]<<<]                                                       paren depth calculation: (brute forced black magic)
                                                                                  '(' => 1
                                                                                  ')' => 255
                                                                                  '0123456789+-*/' => 0 
                         <[->>+<<]                                              accumulate paren depth counter
                                  >>>[->>-<<]                                   preserve a data cell uniquely identifying last character
                                               <[,>>]                         if depth counter is nonzero move to cell identifying last character
                                                     ->[+>[>]--<<<++<+]>.     character to final output calculation: (brute forced black magic)
                                                                                '+-*/(' or \0 => 0
                                                                                '0123456789)' => nonzero
```
[Answer]
# [Pip](https://github.com/dloscutoff/pip), 17 bytes
```
$>^pNa&`[\d)]$`Na
```
Takes the partial expression as a command-line argument. Outputs `0` for open parenthesis, `1` for close parenthesis. [Attempt This Online!](https://ato.pxeger.com/run?1=m724ILNgwYKlpSVpuhYbVeziCvwS1RKiY1I0Y1US_BIh4jDpaCUNQ20NI31jTU1dCy0NpVioBAA)
[Verify all test cases!](https://ato.pxeger.com/run?1=m724ILNgebSSblGOUuzC6qWlJWm6FhtV7OIK_BLVEqJjUjRjVRL8EiHiS2sVfBXSIewFN5O4NAy1QVjDSN8YRmvCGZq6FshsLQ1UnoYpOl8TQ0ATYhUA)
### Explanation
```
$>^pNa&`[\d)]$`Na
                   a is command-line arg; p is "()" (implicit)
  ^p               Split p into a list of two parenthesis characters
    Na             Get the count of each parenthesis in the argument
$>                 Fold on > (1 if there are more open than close parens, 0 otherwise)
                   (Because we "can expect the input to be typed on the calculator,"
                   there will never be more close than open parens)
      &            Logical AND
       `      `    The following regex:
        [\d)]       Either a digit or a close paren
             $      followed by end-of-string
               N   Count matches in
                a  The argument
```
Thus:
* If the parentheses are balanced, `$>` gives `0`, which short-circuits the AND and returns `0` (open paren)
* Otherwise:
	+ If the argument ends with a digit or `)`, return `1` (close paren)
	+ If it doesn't, return `0` (open paren)
To get `(` and `)` as output, wrap the whole thing in `(p` ... `)` for +3 bytes.
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 15 bytes
```
a=>eval(a+')m')
```
[Try it online!](https://tio.run/##jc7BTsMwDIDhe5/C8iU226gAIaFN3Y0nQJwQhyh1u0CXVFk2dZr67CXlgjQESm5WPsv/hz7pgwm2jyvna5naatLVVk66I71QvFc8bYq97qGCSwGgXs4u6uE5BB/W8Opk6MVEqSH6T3HAag2K1PI/aWtx0TZWwow54bFojs5E6x00NPD3oRjOcIE2jRsYwehodiTpC4LEY3CQkt7kHca0XBjvDr6T28631BAiXD9mKEtAwmtKdwvMp3RfPuAvyn9RxnzKqyfMC5jpDWE@pUfMC5hpas6mjD8B0xc "JavaScript (Node.js) – Try It Online")
[tsh](https://codegolf.stackexchange.com/a/237465/) claim that "My function return results via throwing an exception"
[Answer]
# MATLAB, 65 bytes
```
@(x)all([sum(x(x<42)*2-81),feval(@(a,b)a(end)~=b,[0,x],'/*-+(')])
```
[Try it online!](https://tio.run/##bcixDoIwGMTx3RfpXWmDVE1IlIT3IAwf2k4IA0o6@epVFxNil8v9f/P1IatPqUWkjCO65XlHRLwcHbWzdUUT/CojWogZKPDTja9mMN3exN6oUtsCij1TaGRazrsApfhdVMXvwJWHTXBbtPUfaGQIpywyrx9Obw "Octave – Try It Online")
Anonymous function. Outputs logical 1 for `)` and logical 0 for `(`.  
Monstrosity with `eval` is required to handle empty input. Without that case it reduces to:
```
@(x)all([sum(x(x<42)*2-81),x(end)~='/*-+('])
```
which is much easier to comprehend. Ungolfed:
```
@(x)all([                                    % all of the conditions must be met
         sum(x(x<42)*2-81)                   % brackets are unbalanced
                          ,                  % AND
                           x(end)~='/        % last character isn't / AND
                                     *-+('   % isn't * AND ... (so on)
                                          ])
```
Checking of bracket unbalance works by taking only brackets in input: `x(x<42)` and then with multiplication and subtraction transforming `(` into `-1` and `)` into `1`. Then sum of these is converted to logical during execution of `all` - `0` stays logical `0` anything else becomes logical `1`.
Omitted in ungolfed version `eval` additionaly puts `0` before whole input so last character will always exist.
[Answer]
# [Core Maude](http://maude.cs.illinois.edu/w/index.php/The_Maude_System), 206 bytes
```
mod B is pr LIST{Int}. ops b p : Nat ~> Nat . var A : Nat . var X Y Z :[Nat]. eq
b(nil)= 0 . eq b(X A)= 0 ^((~ A & 16)*(A xor 41)+ 0 ^ p(X A)). eq p(nil)=
0 . eq p(A X)= 0 ^(A & 22)* -1 ^(A & 1)+ p(X). endm
```
The result is obtained by reducing the `b` function with the input string given as a list of ASCII code points. The output will be `0` for open bracket and `1` for close bracket.
### Example Session
```
Maude> --- "" -> "("
> red b(nil) .
result Zero: 0
Maude> --- "(1+" -> "("
> red b(40 49 43) .
result Zero: 0
Maude> --- "(1+(2/3" -> ")"
> red b(40 49 43 40 50 47 51) .
result NzNat: 1
Maude> --- "(1+(2/3)" -> ")"
> red b(40 49 43 40 50 47 51 41) .
result NzNat: 1
Maude> --- "(1+(2/3))-8" -> "("
> red b(40 49 43 40 50 47 51 41 41 45 56) .
result Zero: 0
Maude> --- "(1+(2/3))-8*(" -> "("
> red b(40 49 43 40 50 47 51 41 41 45 56 42 40) .
result Zero: 0
Maude> --- "(1+(2/3))-8*((5" -> ")"
> red b(40 49 43 40 50 47 51 41 41 45 56 42 40 40 53) .
result NzNat: 1
Maude> --- "(1+(2/3))-8*((5)" -> ")"
> red b(40 49 43 40 50 47 51 41 41 45 56 42 40 40 53 41) .
result NzNat: 1
Maude> --- "(1+(2/3))-8*((5))" -> "("
> red b(40 49 43 40 50 47 51 41 41 45 56 42 40 40 53 41 41) .
result Zero: 0
```
### Ungolfed
```
mod B is
    pr LIST{Int} .
    ops b p : Nat ~> Nat .
    var A : Nat .
    var X Y Z : [Nat] .
    eq b(nil) = 0 .
    eq b(X A) = 0 ^ ((~ A & 16) * (A xor 41) + 0 ^ p(X A)) .
    eq p(nil) = 0 .
    eq p(A X) = 0 ^ (A & 22) * -1 ^ (A & 1) + p(X) .
endm
```
I hope it's not too cheesy to accept input as ASCII code points. Maude *has* a string module, but it's pretty weak and kind of verbose.
[Answer]
# [Ly](https://github.com/LyricLy/Ly), 50 bytes
```
is<l>0sp["("=l+f")"=fp-sp]<")"=!f'0Lfp*l!+!!")"f-o
```
[Try it online!](https://tio.run/##y6n8/z@z2CbHzqC4IFpJQ8k2RztNSVPJNq1At7gg1gbEVExTN/BJK9DKUdRWVAQKpOnm//@vYagNAA "Ly – Try It Online")
The algorithm for this one is:
* read in the input, store the last character in a separate stack
* run through all the chars, track `(` vs `)` balance in a saved cell
* test, `last="("` and `last<"0"`
* combine those three tests (paren balance is the 3rd one) to pick output
There's a caveat though. I don't think `Ly` can handle null character (as opposed to numeric) input. So it doesn't handle the first test case, which is a null string.
Here's the sausage making...
First part, get input and setup for run
```
i        - read the input onto the stack as codepoints 
 s       - save the last char in the backup cell
  <l>    - switch stacks, load backup cell, switch back to original stack
     0sp - set the backup cell to "0", then delete 0 from stack
```
Count the `(` vs `)` chars, keeping a summary count of the balance
```
[               p] - process one char per iteration, until stack is empty
 "("=              - compare top of stack to "("
     l+            - load balance summary, increments on match
       f           - flip the current character to the top
        ")"=       - compare top of stack to ")"
            fp     - flip current char to the top, delete it
              -    - decrement balance summary if char was ")"
               s   - save balance summary to backup cell
```
Third, test the last character of the input.
```
<            - switch to the stack where we stashed the last char
 ")"=        - compare to ")"
     !       - negate result, we want "not equal"
      f      - pull the character to the top of the stack
       '0L   - test if less than character codepoint for "0"
          fp - pull the char to the top, then delete it
```
Fourth, combine the tests to get an output choice
```
*            - compute "and" of the last two tests
 l!          - load balance summary, negate
   +         - compute "or" of that and the previous test combo
    !!       - convert anything ">0" to "1" via double negate
      ")"f   - add ")" to stack, pull tests results to top
          -  - subtract to change char to "(" if called for
           o - output top of stack as a character
```
]