내가 인터넷에 아무리 검색해도 찾을 수 없던 것 중 하나는 백준에서 인터랙티브 문제를 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 안에 들어있는 코드를 실행하는 상태가 된다. 입력값을 받을 때 마다 전체 코드가 처음부터 다시 실행된다는 착각을 할 수 있기에 명확히 알고 가는것이 중요하다.
'JS' 카테고리의 다른 글
| [숏코딩] JS 기본문법(백준) (0) | 2024.10.21 |
|---|