코드치고 무게치고

[백준-node.js] JavaScript 입력 - vsCode에서 풀기 본문

개발공부/코딩테스트 준비

[백준-node.js] JavaScript 입력 - vsCode에서 풀기

코딩하자영아 2022. 1. 30. 23:40

코딩 테스트 연습할 때 프로그래머스를 주로 사용하여 연습하였다.
프로그래머스를 사용한 제일 큰 이유는 입력이 함수의 매개변수로 들어와서 문제 풀기가 쉽기 때문이다.
하지만 백준싸이트에서 입력을 코드로 직접 받아야 한다. 직접 받는 게 무슨 문제냐고 할 수 있지만 다른 언어에 비해 javascript는 백준에서 입력을 받기가 조금 까다롭다.
그래서 백준을 포기하고 프로그래머스를 사용했는데 이제 조금 더 다양한 문제를 풀기 위해 백준에 도전하려고 한다.

입력을 어떻게 받아야할지 많이 찾아보았는데 아래의 유튜브에서 초보자들이 하기에 잘 정리해주었다. 아래의 영상을 보고 이 글을 작성하기로 했다.
초보자가 자바스크립트로 백준 문제 푸는 법


추가내용

1

const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().split("\n");

위 코드로 input 값을 받아오면 vscode에서는 input.txt로 받을 수 있고
백준같은 리눅스 환경에서는 /dev/stdin으로 받을 수 있다.

2

Node.js 온라인 컴파일러
vsCode에서는 정답인 문제가 백준에서 틀리는 경우가 종종있다.

위 환경은 백준과 같은 리눅스 환경이라 정확히 테스트를 해볼 수 있다.

위 싸이트의 stdin Inuts에 백준 입력 예제를 넣고 테스트해보기 바란다.

3

toString()으로 문자열을 받을 때

const fs = require("fs");
let input = fs.readFileSync("/dev/stdin").toString().trim();

문자열을 toString()으로 변환하여 받을 때에는 양끝에 불필요한 줄바꿈 문자가 남을 수 있다.

이것을 trim()으로 처리하여 저장하자!


vscode로 문제를 푸는 방법이다.

아래의 문제를 예시로 들겠다.
https://www.acmicpc.net/problem/4344

준비

  • node.js: 설치되어 있어야 브라우저 없이 vscode에서 javascript를 돌릴 수 있다.
  • vscode: 이거로 코드를 작성할 것이다.

1.input 파일 및 File System 모듈

위 사진 처럼 input 파일을 만들어서 js 폴더와 같은 위치에 둔다.
파일명은 개인이 정하면 된다. 필자는 input.txt로 하였다.

const fs = require("fs");
let input = fs.readFileSync("./input.txt").toString();

File System을 위와 같이 불러온다.
fs에는 File System 모듈을 가져오는 것이다.
input에는 input.txt파일의 값을 string으로 변환하는 것이다.

이렇게 불러오면 아래와 같이 출력된다.

5
5 50 50 70 80 100
7 100 95 90 80 70 60 50
3 70 90 80
3 70 90 81
9 100 99 98 97 96 95 94 93 91

이렇게 가져온 입력을 바로 사용할 수 없다.
문제에 적용할 수 있게 변환하여 정제하는 과정이 필요한다.

2. input값 변환하기

const fs = require("fs");
let input = fs.readFileSync("./input.txt").toString();
input = input.split("\n");
const inputC = +input[0];
const inputTestCase = [];

for (let i = 1; i <= inputC; ++i) {
  const arr = input[i].split(" ").map((item) => +item);

  let newArr = [];
  for (let j = 1; j < arr.length; j++) {
    newArr.push(arr[j]);
  }
  const testCase = {
    N: arr[0],
    arr: newArr,
  };
  inputTestCase.push(testCase);
}

2-1 라인별 풀이

문제를 풀기 위해 위와 같이 input 값을 변환하였다.

input = input.split("\n");
일단 위의 입력을 줄을 기준으로 나눠서 배열에 저장한다.

[
  '5\r',
  '5 50 50 70 80 100\r',
  '7 100 95 90 80 70 60 50\r',
  '3 70 90 80\r',
  '3 70 90 81\r',
  '9 100 99 98 97 96 95 94 93 91'
]

이러한 값이 출력된다. \r은 환경에 따라 출력될 수도 있고 안될 수도 있다.
유튜브에서는 \r이 나오지 않았지만 나의 환경에서는 출력되었다.
이걸 자른다고 split('\r\n')으로 코드를 작성하면 백준에서는 틀렸다고 나온다.
그러니 \n으로 한줄씩 자르고 \r 은 무시한다.

const inputC = +input[0];
문제에서 테스트 케이스의 개수 C를 따로 저장하는 변수이다.
input[0]은 문자열임으로 + 단항 연산자를 사용하여 number로 변환하여 저장한다.

for (let i = 1; i <= inputC; ++i)
제일 첫 줄 inputC를 제외하고 나머지 줄을 for문을 돌린다.

const arr = input[i].split(" ").map((item) => +item);
arr는 한 줄의 입력값을 따로 배열에 저장한다.
첫 번째 줄로 예시를 들면 [ 5, 50, 50, 70, 80, 100 ]이런 배열로 arr에 저장된다.

let newArr = [];
  for (let j = 1; j < arr.length; j++) {
    newArr.push(arr[j]);
  }

arr의 첫번째 학생의 수를 제외한 입력된 점수를 따로 newArr에 저장하기에 j는 1부터 시작한다.

const testCase = {
    N: arr[0],
    arr: newArr,
  };
inputTestCase.push(testCase);

testCaser에 N은 학생의 수를 arr는 점수의 배열을 넣은 객체로 만들어 inputTestCase 배열에 push 한다.
이렇게 정재를 거치면 아래와 같이 배열에 저장된다.

[
  { N: 5, arr: [ 50, 50, 70, 80, 100 ] },
  { N: 7, arr: [
      100, 95, 90, 80,
       70, 60, 50
    ] },
  { N: 3, arr: [ 70, 90, 80 ] },
  { N: 3, arr: [ 70, 90, 81 ] },
  {
    N: 9,
    arr: [
      100, 99, 98, 97, 96,
       95, 94, 93, 91
    ]
  }
]

이제 프로그래머스처럼 풀 수 있게 함수로 넘겨줄 값이 완성되었다

3. 문제 풀이 세팅

solution(inputC, inputTestCase);

function solution(C, inputTestCase){
  /**
   * 문제 풀이
   */
}

solution이란 함수를 작성하고 위에서 변환한 input값을 매개변수로 넘겨주면 된다.
이렇게 하면 solution함수에서 문제 풀이에 집중하여 풀 수 있다.

4. 정답 제출

const fs = require("fs");
let input = fs.readFileSync("/dev/stdin").toString(); //<-
input = input.split("\n");

const inputC = +input[0];
const inputTestCase = [];

for (let i = 1; i <= inputC; ++i) {
  const arr = input[i].split(" ").map((item) => +item);
  let newArr = [];
  for (let j = 1; j < arr.length; j++) {
    newArr.push(arr[j]);
  }
  const testCase = {
    N: arr[0],
    arr: newArr,
  };
  inputTestCase.push(testCase);
}

solution(inputC, inputTestCase);

function solution(C, inputTestCase) {
  /**
   * 문제 풀이
   */
  console.log("정답출력");
}

문제를 다 풀었다는 가정하에 백준에 정답을 제출하기 전에 변경해야 할 것이 있다.
let input = fs.readFileSync("input.txt").toString(); 를 아래로 변경한다.
let input = fs.readFileSync("/dev/stdin").toString();
readFileSync에 '/dev/stdin'를 넣어야 백준에서 입력값을 받을 수 있다.
그리고 백준의 정답 출력은 프로그래머스처럼 return으로 하는 것이 아닌
console.log로 정답을 출력하면 된다.


위 문제는 하나의 예시이다.
문제마다 입력값을 변환하는 과정은 다를 것이다.
그리고 문제 풀기도 바쁜데 입력값도 만들어야 하나 라는 생각이 들 수 있다.
입력값을 만드는 과정도 하나의 연습이라 생각하고 문제를 풀어보자!

글이 이해가 안 된다면 영상을 보고 해 보시기 바란다!

Comments