카테고리 없음

자바스크립트(Node.js) 로 백준문제 입출력 하기

백준에서 자바스크립트로 알고리즘 문제를 풀어볼 수 있다! 백준에서 Node.js 채점을 지원하기 때문이다.

 

백준 Node.js 지원

 

그런데 예제로 있는 소스를 보면 /dev/stdin 을 readFileSync 함수로 읽어서 표준 입력을 가져오는데...

이거 윈도우에선 안된다!! 그리고 리눅스에서 한다고 해도 일반적인 C/C++/Python 감각으로 입력을 받긴 힘들다.

 

그러면 윈도우에서도 동작하고 한줄만 읽기 등의 동작을 처리할 수 있게 하려면 어떻게할까?

 

Node.js 에 readline 이라는 내장 API가 있긴 하지만... Node.js API 답게 입력을 처리하는게 콜백 구조로 되어있다. 때문에 이걸 그냥 사용하면 코드가 엄청 꼬여버린다. 순서가 직관적이지도 않고, 입력 처리가 복잡해지면 코드 구조가 매우 복잡해지게 된다.

 

그래서 그냥 직접 간단한 헬퍼 코드를 만들었다. 적당한 곳에 solve.js 파일을 만들고 이 코드를 통째로 복사 붙여넣기하고 시작하면 된다. 그리고 문제 풀이 로직을 ps.main 함수에 들어가는 콜백 함수 안에 작성하면 된다. 이 ps.main 함수가 뒤에 나오는 입력 함수들을 쓸 수 있게 해준다.

ps.main 함수

이제 입력을 편하게 하기 위한 여러가지 함수들을 사용할 수 있다.

await ps.readLine()

파이썬의 input() 함수처럼 한 줄을 읽어서 String 형으로 반환한다. 문자열을 읽을 때 편하다.

ps.main(async () => {
  let line1 = await ps.readLine();
  let line2 = await ps.readLine();
  
  ps.writeLine('Line 1: ' + line1);
  ps.writeLine('Line 2: ' + line2);
});

결과

await ps.readArrayLine()

숫자들을 읽을 때 편한데, 한 줄을 읽고 공백 단위로 나눠서 Number 배열 형으로 반환한다.

 

백준 1000번 (A+B)

ps.main(async () => {
  const arr = await ps.readArrayLine();
  ps.writeLine(arr[0]+arr[1]);
});

결과

 

JS 비구조화 문법을 사용하면 더 직관적으로 코드를 작성 할 수 있다.

ps.main(async () => {
  const [a,b] = await ps.readArrayLine();
  ps.writeLine(a+b);
});

ps.writeLine(str) & ps.write(str)

화면에 문자열을 출력한다. console.log 함수와 같은 역할이지만 출력을 포매팅해주는 기능이 없어 조금 더 빠르다.

참고자료

예시는 위 예시들을 참고하면 된다.

ps.range(start, end, step)

입출력과는 상관 없지만 편의를 위해 넣은 함수인데, 파이썬의 range() 함수와 거의 똑같이 동작한다.

ps.main(async () => {
  const [n] = await ps.readArrayLine();

  for (let i of ps.range(n)) {
    ps.write(i + " ");
  }
  ps.writeLine();

  for (let i of ps.range(1, n)) {
    ps.write(i + " ");
  }
  ps.writeLine();

  for (let i of ps.range(2, n, 2)) {
    ps.write(i + " ");
  }
  ps.writeLine();
});

 

 

5를 입력하면 이렇게 된다.

 

주의사항

ps.readLine 과 ps.readArrayLine 함수는 앞에 await 을 꼭 붙여줘야 한다. 안그러면 입력값이 제대로 리턴되지 않는다.

참고 자료

 

추가 예시

백준 2438번 (별 찍기)

ps.main(async () => {
  let [n] = await ps.readArrayLine();

  for (let i of ps.range(n)) {
    for (let j of ps.range(i+1)) {
      ps.write('*');
    }
    ps.writeLine();
  }
});

전체 코드 보기

 

 

 

백준 9655번 (돌 게임)

ps.main(async () => {
  const [n] = await ps.readArrayLine()

  const cache = [...new Array(n+1)].fill(null)

  function f(n) {
    if (n === 1 || n === 3) {
      return true
    }
    if (n === 2) {
      return false
    }

    if (cache[n] !== null) {
      return cache[n]
    }

    let ret

    if (!f(n-1) || !f(n-3)) {
      ret = true
    }
    else {
      ret = false
    }

    return cache[n] = ret
  }

  if (f(n)) {
    ps.writeLine('SK')
  }
  else {
    ps.writeLine('CY')
  }
});

전체 코드 보기

 

 

 

백준 20126번 (교수님의 기말고사)

ps.main(async () => {
  const [n, m, s] = await ps.readArrayLine()

  const timeline = []

  for (const _ of ps.range(n)) {
    const [s, d] = await ps.readArrayLine()
    timeline.push([s, s+d])
  }

  timeline.sort((a, b) => a[0] - b[0])

  let lastend = 0
  for (const i of ps.range(n)) {
    if (timeline[i][0] - lastend >= m) {
      ps.writeLine(lastend)
      return
    }
    lastend = timeline[i][1]
  }

  if (s - timeline[timeline.length-1][1] >= m) {
    ps.writeLine(timeline[timeline.length-1][1])
  }
  else {
    ps.writeLine('-1')
  }

});

전체 코드 보기