kakasoo

[node.js] 리모컨 ( 백준 1107번 ) 본문

프로그래밍/알고리즘 풀이

[node.js] 리모컨 ( 백준 1107번 )

카카수(kakasoo) 2021. 7. 29. 16:27
반응형
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

const input = [];

rl.on("line", (line) => {
    input.push(line);
}).on("close", () => {
    main();
});

/**
 *
 * @param {number} curNumber
 * @param {number[]} brokenButtons
 */
const checkNum = (curNumber, brokenButtons) => {
    const numbers = curNumber.toString().split("").map(Number);

    for (const a of numbers) {
        if (brokenButtons.includes(a)) {
            return false;
        }
    }
    return true;
};

const main = () => {
    const target = Number(input[0]);
    if (target === 100) {
        console.log(0);
        return;
    }

    const brokenButtons = Number(input[1])
        ? input[2]
              .split(" ")
              .filter((el) => !!el)
              .map(Number)
        : [];

    let upDownCount = 0;
    let downNumber = target;
    let upNumber = target;

    while (upDownCount <= 500000) {
        downNumber = target - upDownCount;
        upNumber = target + upDownCount;

        if (0 <= downNumber && checkNum(downNumber, brokenButtons)) {
            const curPushed = String(Math.abs(downNumber)).length + upDownCount;
            console.log(
                Math.abs(target - 100) < curPushed
                    ? Math.abs(target - 100)
                    : curPushed
            );
            return;
        }
        if (checkNum(upNumber, brokenButtons)) {
            const curPushed = String(Math.abs(upNumber)).length + upDownCount;
            console.log(
                Math.abs(target - 100) < curPushed
                    ? Math.abs(target - 100)
                    : curPushed
            );
            return;
        }

        upDownCount++;
    }

    console.log(Math.abs(target - 100));
};

코드가 너무 더러워서 누군가가 참고하기 힘든 코드일 거 같다.
그래도 힌트를 조금 전달하고자 한다.
node.js로 코드를 짜면서 아마도, 실수할 부분이 반드시 있을 것이기 때문이다.

  1. 마이너스에 조심하라. 만약 마이너스의 length를 구하고자 한다면, 문자열 상에서 마이너스 기호 역시 한 글자로 포함될 것이다.
  2. count를 target으로부터 위 아래 값들을 찾아가면서 구하고 있는데, 만약 이런 방식을 채택했다면 반드시 target - count 값을 우선 탐색해야 한다. 예컨대, 8에서 10, 12에서 10은 똑같이 2 차이가 나지만, 8의 length는 12의 length보다 1 작다.

주의할 점


const input = [];

rl.on("line", (line) => {
    input.push(line);
      if (line.length === 3) main();
});

const input = [];

rl.on("line", (line) => {
    input.push(line);
}).on("close", () => {
    main();
});

위의 코드는 제대로 동작하지 않는다.
만약 부서진 숫자 버튼이 없으면 두번째 입력은 0이고 세번째 입력은 빈문자열일 텐데, 이럴 경우 이 문제의 채점에서는 '엔터' 자체를 누르지 않을 것이다.
입력이 끝났단 신호를, 엔터를 통해 명시적으로 받으려 하지 말고 close로 만들자.

반응형