Check whether every bracket in a string is properly closed in the right order. Brackets are (), [] and {}. Other characters are ignored.
Implement is_balanced(s). Then implement first_error(s), returning the index of the first character that makes the string unbalanced: an unexpected closer, or the position of the earliest unclosed opener if the string ends with brackets still open. Return -1 if the string is balanced.
is_balanced("f(a[1], {b: 2})") # True
first_error("(]") # 1
first_error("((x)") # 0