mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-18 15:28:43 +02:00
129 lines
4.1 KiB
TypeScript
129 lines
4.1 KiB
TypeScript
import { exceptionAlert } from "../../utils/helpers/exceptionAlert";
|
|
import { getRandomIntInclusive } from "../../utils/helpers/getRandomIntInclusive";
|
|
import { CodingContractTypes, parseArrayString } from "../ContractTypes";
|
|
import { CodingContractName } from "@enums";
|
|
|
|
export const sanitizeParenthesesInExpression: Pick<
|
|
CodingContractTypes,
|
|
CodingContractName.SanitizeParenthesesInExpression
|
|
> = {
|
|
[CodingContractName.SanitizeParenthesesInExpression]: {
|
|
desc: (data: string): string => {
|
|
return [
|
|
"Given the following string:\n\n",
|
|
`${data}\n\n`,
|
|
"remove the minimum number of invalid parentheses in order to validate",
|
|
"the string. If there are multiple minimal ways to validate the string,",
|
|
"provide all of the possible results. The answer should be provided",
|
|
"as an array of strings. If it is impossible to validate the string",
|
|
"the result should be an array with only an empty string.\n\n",
|
|
"IMPORTANT: The string may contain letters, not just parentheses.\n\n",
|
|
`Examples:\n\n`,
|
|
`"()())()" -> ["()()()", "(())()"]\n`,
|
|
`"(a)())()" -> ["(a)()()", "(a())()"]\n`,
|
|
`")(" -> [""]`,
|
|
].join(" ");
|
|
},
|
|
difficulty: 10,
|
|
generate: (): string => {
|
|
const len: number = getRandomIntInclusive(6, 20);
|
|
const chars: string[] = [];
|
|
chars.length = len;
|
|
|
|
// 80% chance of the first parenthesis being (
|
|
Math.random() < 0.8 ? (chars[0] = "(") : (chars[0] = ")");
|
|
|
|
for (let i = 1; i < len; ++i) {
|
|
const roll = Math.random();
|
|
if (roll < 0.4) {
|
|
chars[i] = "(";
|
|
} else if (roll < 0.8) {
|
|
chars[i] = ")";
|
|
} else {
|
|
chars[i] = "a";
|
|
}
|
|
}
|
|
|
|
return chars.join("");
|
|
},
|
|
getAnswer: (data) => {
|
|
let left = 0;
|
|
let right = 0;
|
|
const res: string[] = [];
|
|
|
|
for (let i = 0; i < data.length; ++i) {
|
|
if (data[i] === "(") {
|
|
++left;
|
|
} else if (data[i] === ")") {
|
|
left > 0 ? --left : ++right;
|
|
}
|
|
}
|
|
|
|
function dfs(
|
|
pair: number,
|
|
index: number,
|
|
left: number,
|
|
right: number,
|
|
s: string,
|
|
solution: string,
|
|
res: string[],
|
|
): void {
|
|
if (s.length === index) {
|
|
if (left === 0 && right === 0 && pair === 0) {
|
|
for (let i = 0; i < res.length; i++) {
|
|
if (res[i] === solution) {
|
|
return;
|
|
}
|
|
}
|
|
res.push(solution);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (s[index] === "(") {
|
|
if (left > 0) {
|
|
dfs(pair, index + 1, left - 1, right, s, solution, res);
|
|
}
|
|
dfs(pair + 1, index + 1, left, right, s, solution + s[index], res);
|
|
} else if (s[index] === ")") {
|
|
if (right > 0) dfs(pair, index + 1, left, right - 1, s, solution, res);
|
|
if (pair > 0) dfs(pair - 1, index + 1, left, right, s, solution + s[index], res);
|
|
} else {
|
|
dfs(pair, index + 1, left, right, s, solution + s[index], res);
|
|
}
|
|
}
|
|
|
|
dfs(0, 0, left, right, data, "", res);
|
|
|
|
return res;
|
|
},
|
|
solver: (data, answer) => {
|
|
const res = sanitizeParenthesesInExpression[CodingContractName.SanitizeParenthesesInExpression].getAnswer(data);
|
|
|
|
if (res === null) {
|
|
exceptionAlert(
|
|
new Error(
|
|
`Unexpected null when calculating the answer for ${CodingContractName.SanitizeParenthesesInExpression} contract. Data: ${data}`,
|
|
),
|
|
);
|
|
return false;
|
|
}
|
|
|
|
if (res.length !== answer.length) return false;
|
|
return res.every((sol) => answer.includes(sol));
|
|
},
|
|
convertAnswer: (ans) => {
|
|
const parsedAnswer = parseArrayString(ans);
|
|
if (
|
|
!sanitizeParenthesesInExpression[CodingContractName.SanitizeParenthesesInExpression].validateAnswer(
|
|
parsedAnswer,
|
|
)
|
|
) {
|
|
return null;
|
|
}
|
|
return parsedAnswer;
|
|
},
|
|
validateAnswer: (ans): ans is string[] => Array.isArray(ans) && ans.every((s) => typeof s === "string"),
|
|
},
|
|
};
|