/**
* Problem:
* Count how many single-character flips (either '(' -> ')' or ')' -> '(')
* would result in a valid parentheses string.
*
* A string is valid if:
* 1. Total balance is 0 (same number of '(' and ')')
* 2. At any prefix, the number of ')' does not exceed '(' (i.e., prefix balance ≥ 0)
*
* Strategy:
* - Use prefixBalance to track balance at each index
* - Use prefixMin to ensure the prefix remains valid
* - Use suffixMinOffset to ensure suffix remains valid after a flip
*
* @param {string} s - Input string of parentheses
* @returns {number} Number of valid single-character flips
*/
function countValidParenthesesFixes(s) {
const n = s.length;
// Step 1: Calculate prefix balance at every index
const balanceAt = Array(n).fill(0); // balanceAt[i] = net balance at s[0..i]
for (let i = 0; i < n; i++) {
const delta = s[i] === '(' ? 1 : -1;
balanceAt[i] = (i > 0 ? balanceAt[i - 1] : 0) + delta;
}
const totalBalance = balanceAt[n - 1]; // Final balance of full string
// Early return: impossible to fix if balance ≠ ±2
if (Math.abs(totalBalance) !== 2) return 0;
// Step 2: Compute prefix minimum balance at each point
const minPrefixBalance = Array(n).fill(0);
minPrefixBalance[0] = balanceAt[0];
for (let i = 1; i < n; i++) {
minPrefixBalance[i] = Math.min(minPrefixBalance[i - 1], balanceAt[i]);
}
/**
* Step 3: Compute suffixMinOffset[i]
* It indicates how deep (min balance drop) the suffix from index i goes.
* Used to detect if suffix becomes invalid after a flip.
*/
const suffixMinOffset = Array(n).fill(0);
suffixMinOffset[n - 1] = 0;
for (let i = n - 2; i >= 0; i--) {
const diff = balanceAt[i + 1] - balanceAt[i];
suffixMinOffset[i] = Math.min(0, suffixMinOffset[i + 1] + diff);
}
// Step 4: Try flipping each character
let validFlipCount = 0;
for (let i = 0; i < n; i++) {
const flipDelta = s[i] === '(' ? -2 : 2;
// Rule 1: total balance after flip must be 0
if (totalBalance + flipDelta !== 0) continue;
// Rule 2: prefix before flip must be valid
if (i > 0 && minPrefixBalance[i - 1] < 0) continue;
// Rule 3: suffix after flip must stay valid
const balanceBefore = i > 0 ? balanceAt[i - 1] : 0;
const newBalanceAtFlip = balanceBefore + (s[i] === '(' ? -1 : 1);
const newSuffixMin = newBalanceAtFlip + suffixMinOffset[i];
if (newSuffixMin >= 0) {
validFlipCount++;
}
}
return validFlipCount;
}
let input = '';
process.stdin.on('data', function (chunk) {
input += chunk;
});
process.stdin.on('end', function () {
const lines = input.trim().split('\n');
for (const line of lines) {
console.log(countValidParenthesesFixes(line.trim()));
}
});