문제 10814번:나이순 정렬

여는 글

Node.js/JavaScript 입력값 받기
나는 항상 이 값 외우는게 어렵다.
node.js 환경에서는 그냥 input 값 하나 만들어서 연습용으로 사용하고 다른 분들이 잘 써두신거 틈틈히 보면서 외우는 중이다.

위의 링크의 작성자 분이 깔끔하게 잘써주셔서 애용한다.

이번 눈높이 개발 챌린지를 신청한 이유는 두가지였다.

  • 다양하게 도전해보자
    이번 코테 챌린지의 목표는 사고력을 키우기도있지만, 실무에서 뚱땡이 코드를 덜짜고 싶은 마음에서 시작했다.
  • 무조건 외우는 방식으로 하지말자
    공식이라는 건 어느정도 효율성과 직결된다 생각한다. 하지만 내 의도와 부합했을 때, 내가 완전히 이해했을 때 해당되는 것이라 생각했다. 일할 땐 급하니까 넘어가더라도 공부할때는 그러지말자였다. 그래서 다른 방법이 있으면 틀려도 수행해보자였다 (한번에 맞으면 더좋고!)

코테 챌린지 7기 OT때, 말씀해주신 방향성과 내 방향성이 부합해서 만족스럽게 수행하고 있다. 회사에 일찍 출근해서 풀고나서 오전 업무 마치고 쉴 때, 후다닥 제출할 문서 작성하는 루틴이 꽤나 보람차고 알차다.

입력값, 출력값

  1. 입력값
  • 첫째 줄에 온라인 저지 회원의 수 N이 주어진다.
  • 둘째 줄부터 N개의 줄에는 각 회원의 나이와 이름이 공백으로 구분되어 주어진다.
  • 나이는 1보다 크거나 같으며, 200보다 작거나 같은 정수이고, 이름은 알파벳 대소문자로 이루어져 있고, 길이가 100보다 작거나 같은 문자열이다.
	3
	21 Junkyu
	21 Dohyun
	20 Sunyoung

→ 즉, 여러줄로 받아야하므로 아래의 코드를 먼저 작성한다.

const fs = require("fs");
const lines = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
  1. 출력값
  • 첫째 줄부터 총 N개의 줄에 걸쳐 온라인 저지 회원을 나이를 출력.
  • 나이가 같으면 가입한 순으로 한 줄에 한 명씩 나이와 이름을 공백으로 구분해 출력한다.

다양한 도전 방법

직관적인것을 지키면서 가독성을 나름 좋게 쓰고싶었다.
그래서 최대한 직관적이게 쓰고 불필요한 로직들을 하나씩 처리해봤다.

1. 첫번째 접근 방법

const fs = require("fs");
const lines = fs.readFileSync("/dev/stdin").toString().trim().split("\n");

const [n, ...students] = lines;

const member = students.map((student, index) => {
  const [age, name] = student.split(" ");
  return { age: parseInt(age), name, index };
});

member.sort((a, b) => a.age - b.age || a.index - b.index);

member.forEach((student) => {
  console.log(`${student.age} ${student.name}`);
});
  • 배열을 직관적으로 풀이한다는 생각으로 인덱스값이 포함된, 포맷이 정돈된 배열을 만들고
  • 이 배열을 다시 나이대로 비교한다. 가입순으로 비교한다고해서 인덱스 까지 비교를 해봤다.

하지만 생각해보니, 어차피 차례대로 순회할텐데 너무 과한 생각이 들었다. 역시나 메모리도 시간도 많이 잡아먹는 듯했다.

2. 두번째 접근 방법

const fs = require("fs");
const lines = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
const [n, ...students] = lines;
const sortedStudents = students
  .sort((a, b) => a.split(" ")[0] - b.split(" ")[0])
  .map((v) => v.split(" ").join(" "))
  .join("\n");

console.log(sortedStudents);
  • 필요없는 배열을 줄여보자, 사실 forEach도 불필요한 것 같아서 지웠다. join을 쓰면 간단할 것 같더라.
  • 나이가 같을 시, 가입순으로 구분한다길래 인덱스도 비교했으나 결국 차례대로 자리수를 비교하기 때문에 불필요할 것 같아 줄였다.

3. 세번째 접근 방법

const fs = require("fs");
const lines = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
const [n, ...students] = lines;
const sortedStudents = students
  .sort((a, b) => a.split(" ")[0] - b.split(" ")[0])
  .map((item) => item.split(","))
  .join("\n");

console.log(sortedStudents);
  • split(" ")과 join(" ")이 한 번 더 들어가는 건 불필요해서 제거했다.

4. 네번째 접근 방법

const fs = require("fs");
const lines = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
const [n, ...students] = lines;
const studentArray = students.sort((a, b) => a.split(" ")[0] - b.split(" ")[0]).join("\n");

console.log(studentArray);
  • 3번째 방법의 split도 한 번 더 왜 썼지 싶다..바로 join으로 처리하면 될 것을.

결론

앞으로 메서드를 정확한 의도로 잘 쓰고있는지 한 번 더 고민해야겠다.
예상치 못한 곳에서 뚱뚱한 함수를 만들고 있을 줄이야..
시간 복잡도에 대해 좀 더 고민해보고, 한 번 익힌 메서드 다시 한 번 보자.

profile
코드도 짜고, 근육도 짜고

0개의 댓글