처음으로 코딩테스트를 준비하는 분들은 코딩테스트를 위해서 어떤 언어를 선택하는 것이 좋을지 한번쯤은 고민해보셨을 것 같습니다. 전공생이신 분들은 학교에서 적어도 2~3가지의 언어를 접하니, 선택지가 다양해서 더 고민이 됩니다. Show
일반적으로 코딩테스트를 준비할 때에는 C++이 가장 목적적합하다고 합니다제가 존경하는 바킹독 형님께서도 C++언어를 추천하고 있습니다. 바킹독 형님께서는 자바나 파이썬은 동작 속도가 느려 전수조사 문제에서 손해를 보고 인터넷 상의 자료도 C/C++에 비해 많이 부족하기 때문에, 자바나 파이썬으로 코딩테스트를 응시하려는 분들께 시간이 많으면 C++로 옮겨타서 코딩테스트를 보는 걸 권하고 있습니다. 그러나 저는 Javascript로 코딩테스트를 준비합니다코딩테스트를 준비하는 이유, 다르게 말하면 알고리즘을 공부하는 이유는 무엇일까요? 저는 프론트엔드 개발자가 되고 싶습니다. 많은 프로그래밍 분야 중에 프론트엔드를 선택한 이유 중의 일부는 방대한 Javascript 생태계와 활발한 커뮤니티, 문법의 자유로움입니다. 수학을 좋아하고 알고리즘도 좋아하지만, 알고리즘 대회에 입상을 꿈꾸거나 이를 전공으로 하는 대학원에 들어가기 위해서 알고리즘을 공부하지 않습니다. 저는 프론트엔드 개발자로서 갖추어야 할 기본 알고리즘 소양을 기르기 위해서, Javascript에 대한 문법적, 실체적 지식을 갖추기 위해서, 그리고 신입 개발자로 입사하기 위한 코딩테스트를 통과하기 위해서 알고리즘을 공부합니다. 다행히 요즘 빅테크기업들은 코딩테스트용 언어로 Javascript를 지원하는 경우가 꽤나 있는 것 같습니다. 적어도 제가 지원하고 싶어하는 기업들은 꽤 지원을 하고 있습니다. 코딩테스트에서 정식으로 Javascript를 지원하는 이상, 느린 속도로 인해 시간 초과가 발생할 걱정은 하지 않아도 되는 것 같습니다. (제대로 된 알고리즘으로 문제를 풀었다는 가정하에서...) 따라서, 프론트엔드 개발자로서 계속 사용하게 될 Javascript에 대한 지식을
함양하기 위해서는 Javascript로 코딩테스트를 준비하는 것도 괜찮은 선택이라고 생각합니다. 또한, C++, Python, Java에 대한 어느 정도의 기초 지식이 있다면, 막히는 문제가 있다면 다른 언어로 작성된 해답을 보면서 문제 해결의 아이디어를 얻을 수 있습니다. Javascript로 코딩테스트를 준비하는데 자료가 빈약한 것은 사실입니다콘솔창으로부터의 입력도 처음에는 어떻게 해야 할지 막막할 수 있습니다. nodejs로 express 서버는 돌려보았지만, 입출력 스트림을 다뤄보는 일은 잘 없으니까요. 참고로, 저는 '실행속도' 보다는 'ES6+ 문법'에 조금 더 초점을 맞춘 풀이 및 팁을 말씀드릴 예정입니다. '실행속도 따위는 신경쓰지 않겠어' 보다는, 어차피 '실행속도'를 고려한다면 다른 언어를 선택하는 것이 맞기 때문에, 조금 실행속도가 느리더라도 Javascript다운 코드로 문제를 풀어갈 계획입니다. 결론: 저와 같은 생각을 가지시고 Javascript로 코딩테스트를 준비하겠다는 분은 앞으로 제가 제시하는 팁을 참고해주시면 감사하겠습니다.도입코딩테스트는 일반적으로 아래의 3단계로 구성됩니다. Baekjoon Online Judge(이하 "BOJ")는 위와 같은 흐름이나, Programmers 같은 경우에는, 입출력 처리에 골머리를 썩을 필요가 없으나, 따라서 Javascript(Node.js)로 코딩테스트 준비시의 입출력 처리방법에 대해서 정리해보겠습니다. 0. "use strict"입출력에 앞서서, 간단하게 "use strict"에 대해서 언급하고자 합니다. 따라서, 항상 "use strict"를 사용합시다. 참고: Strict mode 1. 입력BOJ에서 Node.js의 입출력에 대하여
아래와 같이 언어 도움말에서 제공하고 있습니다.
1-1. fs vs readline결론: 항상 fs모듈을 사용합니다.코딩테스트에서 입력을 받은 뒤에 계산을 하고 출력을 합니다. 계산 도중에 인터랙티브하게 유저로부터 입력을 받는 일이 없습니다. 따라서, 이벤트 드리븐 방식의 복잡한 readline 모듈을 사용할 필요가 전혀 없습니다. 항상 fs.readFileSync(0, "utf8")을 사용합시다. 아래는 fs모듈과 readline모듈에 대하여 블로그를 작성하기 위하여 공부하면서 정리한 내용인데, 크게 중요하지는 않으므로 스킵하셔도 좋습니다. 1-1-1. fs 모듈
참고: Node.js v14.15.4 Documentation - File system 1-1-2. readline 모듈
'line'이벤트는 입력 스트림이 줄바꿈(end-of-line) 입력(\n, \r, \r\n)을 받을 때마다 발생합니다. 주로 유저가 'Enter'나 'Return'을 입력한 경우에 발생합니다. 리스너 함수는 유저로부터 입력된 한 줄을 인자로 하여 호출됩니다.
'close'이벤트는 아래 중 하나가 발생할 때 발생합니다.
리스너 함수는 아무런 인자를 넘겨받지 않고 호출됩니다. 따라서, readline 모듈을 사용할 경우에는, 각 줄이 입력될 때마다 'line' 이벤트가 매번 발생하여 이를 변수에 저장하며, 'close' 이벤트가 발생한 경우 저장된 변수를 가지고 계산을 진행하게 됩니다. 이를 코드로 나타내면 아래와 같이 되는데, 굳이 fs모듈의
1-2. string -> number 자료형 변환: Number vs new Number vs parseInt결론: Number 또는 parseInt를 사용합시다.1-2-1. Number vs new Number
큰 차이가 없어 보이지만, 차이는 있습니다.
혼란을 피하기 위하여 new Number는 사용하지 않습니다. 1-2-2. Number vs parseInt
경험적으로
(참고: new Number() vs Number()) 1-3. ES6+BOJ에서 Node.js의 실행환경은 아래와 같습니다.
Node.js의 현재(2021-01-12 Tue) 기준 최신 버젼은 15.5.1이며 LTS는 14.15.4입니다. 따라서, BOJ에서 v14.15.0 Node.js 환경을 제공한다는 것은, 안정적이고 신뢰도 높은 최신 기능들 대부분을 사용할 수 있다는 뜻입니다. 1-3-1. const, letJavascript로
코딩테스트를 제출하는 사람들 중 많은 사람들의 실수가, 함수 스코프 var와 블록 스코프 const, let을 혼용하는 점이라고 합니다. 위의 예제에서는 일관성있게 var를 사용하였습니다. 그러나 알고리즘 문제 풀이시 함수 스코프를 써야만 할 일은 없을 것 같습니다. 어느 곳에서나 접근하고 싶다면 그냥 최상위 스코프에서 변수를 정의하면 됩니다. 또한 BOJ에서의 Node.js 실행환경에서는 ES6를 지원하므로 블록 스코프인 const, let을 쓰는 것이 좋을 것 같습니다.
개인적으로 입력값은 불변값으로 다루는 것이 좋다고 생각합니다. 입력값은 말그대로 문제에서 주어지는 값이므로, 이를 변경할 일은 없는 것이 일반적입니다. 후에 for문이나 조건문 등에서 사용될 때에 입력값을 변경하여 오류가 생기는 일을 막을 수 있습니다. 따라서 모두 const로 변수를 선언합니다. 1-3-2. destructuringdestructing을 이용한다면 a,b를 아래와 같이 정의할 수 있습니다.
참고로
2. 출력
아래는 BOJ 15649번 문제 N과 M (1)의 채점결과입니다. 위에는 계산 종료후 코드의 마지막에 한번만 출력을 해준 경우이고, 아래는 계산 중간중간에 계속해서 출력을 해준 경우입니다. 보시다시피 실행 시간의 차이가 엄청 많이 나신다는 것을 알 수 있습니다.
※ 참고URL: Node.js v14.15.4 Documentation - Writable Stream: writable.write(chunk[, encoding][, callback]) |