백준에서 js로 인터랙티브 문제를 푸는 방법에 대하여
목차
내가 인터넷에 아무리 검색해도 찾을 수 없던 것 중 하나는 백준에서 인터랙티브 문제를 js로 푸는 방법이었다.
다른 언어는 buffer를 비우는 방법이나, 인터랙티브 문제에서 다시 입력을 받아오는 방법이 잘 설명되어 있지만.. buffer가 뭔지 js에 그런 게 있는지도 모르는 사람들은 결국 인터랙티브 문제에 도전조차 할 수 없게 될 것이다. GPT도 잘못된 코드를 주는 상황에서, 나는 이러한 내용을 설명하는 글의 필요성을 느끼게 되었다.
1. 입력 받기#
많은 사람들이 readline보다는 fs 방법을 선호하고(아마도?), 나 역시 fs를 사용해서 입력값을 받는다. 하지만 인터랙티브 문제는 실시간으로 상호작용을 해야 하기 때문에, 한 번에 입력값을 가져오고 끝나는 fs가 아닌, 한 줄씩 읽는 readline이 필수적이다. 이렇게 입력을 받자.
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
rl.on('line', (line) => {
// 입력 받은 값 처리하기
rl.close() // 코드 실행 종료하기
})입력값이 있을 때마다, rl.on이 실행되고 line에는 그 줄의 내용이 담기게 된다. rl.close()는 단순히 코드를 멈추는 게 아니라 실행을 종료하는 것이기 때문에 실행이 끝났을 때만 사용해야 한다.
2. 출력하기#
buffer란 내용을 이해할 필요는 없다. js에서는 process.stdout.write를 console.log 대신 사용하면 된다.
가장 주의해야 할 점은, process.stdout.write에 넣는 모든 값은 String 타입이어야 한다. 따라서 숫자만을 출력할 때에도 String()으로 감싸는 습관이 필요하다. process.stdout.write는 자동 줄바꿈이 없기 때문에, console.log에 익숙한 사람이라면 아래와 같이 사용하는 것을 선호할 수도 있다.
function print(s) {
process.stdout.write(String(s) + '\n')
}
print('test')3. 예시#
https://www.acmicpc.net/problem/30917
가장 기본적인 인터랙티브 문제이다. 아래와 같이 해결할 수 있다.
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
var a = 1
var ak = 0
var b = 1
process.stdout.write("? A 1\n")
rl.on("line", (line) => {
const input = +line.trim()
if(ak){
if(input == 1) {
process.stdout.write("! "+(a+b))
rl.close()
}else b++
}else {
if(input == 1) {
ak = 1
}else a++
}
if(!ak) process.stdout.write('? A ' + a + '\n')
else process.stdout.write('? B ' + b + '\n')
})rl.close()가 실행되기 전까지 코드는 계속 대기 상태이고, 처음 코드를 실행하면서 a, ak, b 등을 정의하고 난 뒤부터는 입력값이 들어오면 rl.on 안에 들어 있는 코드를 실행하는 상태가 된다. 입력값을 받을 때마다 전체 코드가 처음부터 다시 실행된다는 착각을 할 수 있기에 명확히 알고 가는 것이 중요하다.
댓글