수식 최대화

function calculate(former, operator, latter) {
  let result;
  switch (operator) {
    case "*": {
      result = former * latter;
      break;
    }
    case "+": {
      result = former + latter;
      break;
    }
    case "-": {
      result = former - latter;
      break;
    }
  }
  return result;
}

function solution(expression) {
  // expression을 숫자와 연산자로 구분
  const copied = expression.slice().split("");
  const splitted = [];
  let idx = 0;
  while (idx < copied.length) {
    if (isNaN(parseInt(copied[idx]))) {
      const num = parseInt(copied.splice(0, idx).join(""));
      const operator = copied.shift();
      splitted.push(num, operator);
      idx = 0;
      continue;
    }
    idx++;
    if (idx == copied.length) {
      splitted.push(parseInt(copied.join("")));
    }
  }

  // 연산자만 따로 추출
  const operators = Array.from(
    new Set(splitted.filter((char) => isNaN(parseInt(char))))
  );

  // 순열을 사용하여 연산자들의 우선 순위 리스트를 만든다.
  const orders = [];
  function makeOrders(arr, result) {
    if (arr.length == 0) {
      orders.push(result);
      return;
    }
    for (let i = 0; i < arr.length; i++) {
      const copiedArr = arr.slice();
      const copiedResult = result.slice();
      copiedResult.push(copiedArr[i]);
      copiedArr.splice(i, 1);
      makeOrders(copiedArr, copiedResult);
    }
    return arr;
  }
  makeOrders(operators, []);

  // 각 우선순위 조합별로 연산을 진행한 후, 최대값 도출
  return orders.reduce((acc, opers) => {
    let copiedExp = splitted.slice();
    opers.forEach((oper) => {
      let idx = 0;
      while (idx < copiedExp.length) {
        if (copiedExp[idx] == oper) {
          const calculated = calculate(
            copiedExp[idx - 1],
            oper,
            copiedExp[idx + 1]
          );
          copiedExp.splice(idx - 1, 3, calculated);
          idx = 0;
          continue;
        }
        idx++;
      }
    });
    const value = Math.abs(...copiedExp);
    if (value > acc) {
      acc = value;
    }
    return acc;
  }, 0);
}

0개의 댓글