JS' 공부흔적

[JavaScript] 백준 문제를 풀기 위한 입출력 설정 방법 (fs 모듈) 본문

JavaScript

[JavaScript] 백준 문제를 풀기 위한 입출력 설정 방법 (fs 모듈)

이준수 2023. 1. 1. 00:29

2023년의 첫 번째 글 !!

프로그래머스의 경우, 입출력을 상관하지 않고 함수만 작성해주면 되었지만 백준에서는 입출력을 직접 해줘야한다. 프론트엔드 직군을 준비하면서 자바스크립트로 코딩테스트를 준비한다면 백준에서 node.js를 선택해야하는데, 이때 입력값을 받는 과정이 꽤 복잡하다. 2가지 방법이 있는데 fs 모듈을 사용하는 방법과 readline을 사용하는 방법이다. readline은 시간초과가 날 때가 있다고 하니 이 글에서는 fs 모듈을 사용하는 방법에 대해 작성한다.

 

우선, 예제 입력으로는 아래 입력을 사용하겠다. 참고로 백준 1260번 문제이다.

https://www.acmicpc.net/problem/1260

example.txt 파일을 생성하여 아래 입력값을 붙여준다.

4 5 1
1 2
1 3
1 4
2 4
3 4

 

코드를 입력할 js 파일을 만든 후, 아래 코드를 작성한다.

const fs = require(`fs`); // fs 모듈을 불러옴
const file = process.platform==='linux'?'/dev/stdin':'example.txt';
const inputData = fs.readFileSync(file).toString().trim().split('\n');

 

백준의 채점 환경은 리눅스인데, 백준에서 채점을 진행할 때는 /dev/stdin 으로 설정한 후 코드를 제출해야 한다. 그 외에 로컬에서 테스트할 때는 example.txt를 불러와서 입력값을 받아온다. 두 번째 줄이 그 코드이다. 세 번째 줄은 파일을 읽어와서 입력값을 정제하는 과정이다. 우선 입력값을 문자열로 변환한 후에 trim() 함수가 쓰였는데 입력값을 받아올 때 양 끝에 존재하는 공백 때문에 에러가 발생하는 경우가 있다고 한다. 따라서 trim()을 통해 양 끝에 공백을 제거해줬다. 그 후 줄바꿈 문자를 기준으로 입력값을 나눠주었다. inputData를 출력해보면 아래와 같이 나온다.

[ '4 5 1\r', '1 2\r', '1 3\r', '1 4\r', '2 4\r', '3 4' ]

이스케이프 문자인 \r이 남아있는 것을 볼 수 있는데 이때는 .split('\n')이 아닌 .split('\r\n')으로 작성하면 아래와 같이 잘 나온다.

[ '4 5 1', '1 2', '1 3', '1 4', '2 4', '3 4' ]

그러나 제출할 때는 .split('\r\n')로 작성하게 되면 오답 처리가 되므로 테스트할 때만 위와 같이 진행하고 제출할 때는 .split('\n')로 바꿔서 해야 한다.

 

백준 1260번 문제를 보면 입력값의 첫 줄인 4 5 1이 각각 N, M, V 변수에 해당하고, 그 후에 나오는 1 2, 1 3, 1 4, 2 4, 3 4는 서로 연결할 두 정점들의 배열임을 알 수 있다. 이러한 정보를 가지고 입력값을 추가로 정제해보자. 우선 inputData[0]에 해당하는 4 5 1을 각각 N, M, V에 나눠줘야 한다. 따라서 아래와 같이 작성할 수 있다.

const NMV = inputData[0].split(' ').map(d=>+d);
console.log(NMV); // [ 4, 5, 1 ]

const N = NMV[0], M = NMV[1], V = NMV[2];

inputData[0]에 해당하는 '4 5 1'을 공백을 기준으로 구분하여 배열로 변환했다. 그러나 이렇게 변환된 배열의 각 요소는 string 타입이다. 이 문제의 입력값은 모두 숫자이므로 문자열을 숫자로 바꿔주는 작업이 필요하다. 그 작업이 바로 .map(d=>+d)이다. map 함수를 통해 배열의 각 요소를 모두 돌면서 숫자로 변환해준다. +d는 Number(d)와 같은 역할을 한다.

 

이번엔 서로 연결할 두 정점들의 배열을 만들어보자. inputData[0]은 이미 사용했으므로 1번 인덱스부터 반복문을 돌아야한다.

let nums=[];

for(let i=1;i<inputData.length;i++){
    let tmp=inputData[i].split(' ').map(d=>+d);
    nums.push(tmp);
}

console.log(nums);
// [ [ 1, 2 ], 
//   [ 1, 3 ], 
//   [ 1, 4 ], 
//   [ 2, 4 ], 
//   [ 3, 4 ] ]

inputData[0]을 정제할 때와 같은 방법으로 숫자 배열로 변환했다. 이렇게 데이터를 잘 다듬은 후에 아래와 같이 함수를 만들어주면 프로그래머스와 유사하게 문제를 풀 수 있게 된다.

function solution(N, M, V, nums){
    
    ...

}

solution(N, M, V, nums);

 

입력값을 불러와서 이렇게 사용하기 좋게 다듬는 과정이 정말 익숙하지 않고 어렵겠지만, 무작정 외우지 않고 이해하며 공부하다 보면 익숙해질 것이라고 믿는다.

728x90
반응형