0386

개발

[백준] 27918 - 탁구 경기

문제 링크 : https://www.acmicpc.net/problem/27918

| 문제 탐색하기

1) 목표

: 입력 값을 바탕으로 달구와 포닉스의 점수를 X:Y 형식으로 출력한다.

2) 기능 명세서

(1) 입력받기

  • 표준 입력을 통해 경기의 수와 예측을 입력 받는다.

  • 입력 받은 내용을 줄바꿈을 기준으로 분리하여 배열로 저장한다.

(2) 분해하기

  • 배열을 구조분해 할당하여 경기의 수와 예측을 변수로 분해한다.

(3) 계산하기

  • 각 예측마다 달구와 포닉스의 점수를 증가한다.

  • 만약, 달구와 포닉스의 점수차가 2점이 된다면 그 즉시 결과를 반환한다.

(4) 출력하기

  • 반환된 결과를 출력한다.

| 고민이 되었던 부분

1) 격차가 2가 되었을 때의 기준

: 격차가 2가 되었다는 것은 달구 점수 - 포닉스 점수 혹은 포닉스 점수 - 달구 점수가 2라는 것인데, 이를 절대값으로 계산해서 얻어야 했었다. JS에서 절대값을 구하는 방법은 Math.abs 메서드를 사용하는 방식이었고, 이 방식을 사용해서 조건문을 세울 수 있었다.

2) 결과 출력문은 어떻게 반환할지

: D, P의 값을 주어진 포맷에 맞춰 어떻게 반환할지 고민이 됐다. JS에서는 변수를 문자열 안에 사용할 때 ${변수명}을 빽팃 안에서 사용한다는 것을 사용하여 `${D}:${P}`와 같이 반환하도록 했다.

| 처음 코드 & 개선이 필요한 점

JavaScript
function printResult(inputs) {
  const [N, ...arr] = inputs;

  let D = 0;
  let P = 0;
  for (choice of arr) {
    if (choice === "D") D++;
    if (choice === "P") P++;

    if (Math.abs(D - P) >= 2) {
      return `${D}:${P}`;
    }
  }

  return `${D}:${P}`;
}

function main() {
  const fs = require("fs");
  const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
  const output = printResult(input);
  console.log(output);
}

if (require.main === module) {
  main();
}

module.exports = {
  printResult,
};

1) N을 받고 있지만, 사용하지 않음

: N을 구조 분해로 받았지만, 사용하지 않기에 변수를 선언할 때 N을 삭제한다.

JavaScript
const [, ...arr] = inputs;

2) choice가 선언되지 않음

: let 또는 const 없이 사용되었다. JS에서는 암묵적 전역 변수가 되었기에, 런타임 에러를 방지하고자 고쳐야 한다.

JavaScript
for (const choice of arr) {

3) 조건문 중복

: 논리적으로 문제는 없지만, 상호 배타적인 조건이므로 else if가 더 명확하다.

JavaScript
if (choice === "D") {
  D++;
} else if (choice === "P") {
  P++;
}

4) 조기 종료 로직은 좋지만, 의미가 드러나지 않음

: 로직 자체는 매우 좋지만, 다만 2라는 숫자의 의미가 코드에 드러나지 않는다.

JavaScript
const LIMIT = 2;

if (Math.abs(D - P) >= LIMIT) {
  return `${D}:${P}`;
}

| 최종 코드

JavaScript
function printResult(inputs) {
  const [, ...arr] = inputs;

  let D = 0;
  let P = 0;
  const LIMIT = 2;

  for (const choice of arr) {
    // 예측 판별
    if (choice === "D") {
      D++;
    } else if (choice === "P") {
      P++;
    }

    // 격차 쳌
    if (Math.abs(D - P) === LIMIT) {
      break;
    }
  }

  // 결과 반환
  return `${D}:${P}`;
}

function main() {
  const fs = require("fs");
  const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
  const output = printResult(input);
  console.log(output);
}

if (require.main === module) {
  main();
}

module.exports = {
  printResult,
};

| 느낀점

이번 문제의 로직 자체는 어렵진 않았지만, JS의 기본 실력에 대해서 돌아보게 된 문제였다. 조금 더 JS의 문법과 함수들에 대해서 더 사용해봐야겠다는 생각이 든다. 무엇보다 돌아간다고 해서 안주하는 것이 아니라, 코드를 보면서 부족하거나 잘못된 점이 없는지 디버깅하는 자세를 더 가져보려고 한다.