본문 바로가기

Algorithm/99클럽

[99클럽] 비기너 코딩테스트 스터디 TIL - 백준, 1755

728x90

 

1. 문제풀이

1) 문제

79를 영어로 읽되 숫자 단위로 하나씩 읽는다면 "seven nine"이 된다. 80은 마찬가지로 "eight zero"라고 읽는다. 79는 80보다 작지만, 영어로 숫자 하나씩 읽는다면 "eight zero"가 "seven nine"보다 사전순으로 먼저 온다.

문제는 정수 M, N(1 ≤ M ≤ N ≤ 99)이 주어지면 M 이상 N 이하의 정수를 숫자 하나씩 읽었을 때를 기준으로 사전순으로 정렬하여 출력하는 것이다.

 

입력

첫째 줄에 M과 N이 주어진다.

 

출력

M 이상 N 이하의 정수를 문제 조건에 맞게 정렬하여 한 줄에 10개씩 출력한다.

2) 해석

 

  • M이상 N이하의 정수를 영어로 숫자 하나씩 읽었을 때 기준으로, 사전순으로 정렬하여 출력
  • 정수로 한 줄에 10개씩 출력
  • 우선 영어 배열 만들기 > index로 치환
  • 반복문으로 치환한 후, map에 넣기
  • 영어 순서대로 정렬
  • 정렬한 영어를 다시 정수로 치환
  • 10 단위로 잘라서 출력

 

 

3) 풀이

const en = [
  "zero",
  "one",
  "two",
  "three",
  "four",
  "five",
  "six",
  "seven",
  "eight",
  "nine",
];

const fs = require("fs");
const input = fs.readFileSync("./index.txt").toString().trim().split(" ");

const [M, N] = input.map((num) => Number(num));
const strMap = new Map();

for (let i = M; i <= N; i++) {
  //i를 나누기 > 두 자리수면 하나하나 넣어야 함
  const numArr = i.toString().split("");

  //영어로 치환
  const str = numArr.map((num) => en[num]).join("");
  strMap.set(str, i);
}

//정렬
const sortArr = [...strMap.keys()].sort();

//다시 숫자로 치환
const result = sortArr.map((en) => strMap.get(en));

for (let i = 0; i < result.length; i += 10) {
  console.log(result.slice(i, i + 10).join(" "));
}

 

const en = [
  "zero",
  "one",
  "two",
  "three",
  "four",
  "five",
  "six",
  "seven",
  "eight",
  "nine",
];

 

우선 숫자를 문자로 바꾸기 위해서, 문자 배열을 만들어준다.

index를 이용해서 바꿔줄 것이기 때문에 0-9까지 순서대로 입력해 준다. 

 

const [M, N] = input.map((num) => Number(num));
const strEnMap = new Map();

 

M과 N을 변수에 담아주고, 영어를 key로 숫자와 영어를 담아줄 Map을 만들어준다. 

추후에 치환된 영어를 다시 숫자로 바꿔야 하기 때문에 Map으로 만들어줬다. 

 

for (let i = M; i <= N; i++) {
  //i를 나누기 > 두 자리수면 하나하나 넣어야 함
  const numArr = i.toString().split("");

  //영어로 치환
  const str = numArr.map((num) => en[num]).join("");
  strMap.set(str, i);
}

 

이제 반복문을 통해 숫자를 영어로 치환한 후, Map에 넣어준다.

 

이때 두 자릿수 숫자는 하나하나 치환해야 하기 때문에 문자로 변환한 후, split()를 통해 쪼개준다. 

그리고 map을 이용해 영어로 치환한 후, join()으로 합쳐준다.

추후에 영어를 숫자로 바꿔야 하기 때문에 영어를 key로 map에 넣어준다.

 

//정렬
const sortArr = [...strMap.keys()].sort();

//다시 숫자로 치환
const result = sortArr.map((en) => strMap.get(en));

//출력
for (let i = 0; i < result.length; i += 10) {
  console.log(result.slice(i, i + 10).join(" "));
}

 

Map의 key를 기준으로 정렬시키고, 숫자로 치환해 준다.

마지막으로 for문과 slice를 이용해 10개씩 출력해 준다. 

 

- 걸린 시간

 

 

2. 리팩토링

const fs = require("fs");
const input = fs.readFileSync("./index.txt").toString().trim().split(" ");

const [M, N] = input.map((num) => Number(num));

const numberToEnglish = (num) =>
  num
    .toString()
    .split("")
    .map((digit) => en[digit])
    .join("");

const numToEnMap = new Map();
for (let i = M; i <= N; i++) numToEnMap.set(numberToEnglish(i), i);

const sortedNumbers = [...numToEnMap.keys()]
  .sort()
  .map((en) => numToEnMap.get(en));

//출력
for (let i = 0; i < sortedNumbers.length; i += 10) {
  console.log(sortedNumbers.slice(i, i + 10).join(" "));
}

 

 

우선 숫자를 영어로 바꾸는 부분을 하나로 합쳐서 함수로 빼줬다. 

그 후, 변수명을 좀 더 직관적으로 바꿔주고 sort랑 map 부분을 체이닝으로 연결해 줬다. 

 

성능은 크게 변한 게 없지만 훨씬 가독성이 좋아진 느낌이다~!

 

728x90
반응형