[소프티어] 전광판 | JavaScript | padStart(), padEnd()

예구·2023년 8월 4일
0

Softeer

목록 보기
4/13
post-thumbnail

문제출처

1. 문제

현대차그룹에 다니는 당신은 전세계 유가 변동에 대해 실시간으로 파악하기 위해 사무실에 유가를 실시간으로 표시하는 전광판을 설치하였다. 전광판은 최대 다섯 자리의 자연수만을 표시할 수 있도록, 아래와 같이 육각형 모양의 전구 7×5=35개로 구성되어 있다.

전광판_구성_사진

8자 모양의 전구 묶음은 0부터 9까지의 숫자를 표현할 수 있으며, 표현 방법은 아래와 같다. 아래 그림에서 전구가 켜졌으면 검정색, 꺼졌으면 옅은 회색으로 표현되었다.

전광판_숫자_표시

예를 들어, 전광판을 통해 9881를 표현하면 아래와 같다. 만의 자리 수가 없기 때문에, 만의 자리에 해당하는 전구들이 모두 꺼져 있음에 유의하라.

전광판_예시_1

예를 들어, 전광판을 통해 10724를 표현하면 아래와 같다.

전광판_예시_2

각각의 전구에는 스위치가 달려 있다. 전구에 달려 있는 스위치를 누를 때, 그 전구가 켜져 있었다면 꺼지고, 그 전구가 꺼져 있었다면 켜진다.

지금 전광판에 자연수 A가 표시되어 있는데, 유가가 변동됨에 따라 전광판에 표시된 자연수를 B로 바꿔야 한다. 이러한 목표를 달성하기 위해 스위치를 최소 몇 번 눌러야 하는지를 구하는 프로그램을 작성하라.

제약조건

하나의 입력에서 1개 이상 1000개 이하의 테스트 케이스를 해결해야 한다.
A와 B는 한 자리 이상 다섯 자리 이하의 자연수이다.
A와 B는 숫자 0으로 시작하지 않는다.
A와 B는 서로 다르다.

입력형식

첫 번째 줄에 해결할 테스트 케이스의 수 T가 주어진다.
다음 T개의 줄에는 한 줄에 테스트 케이스 하나씩이 주어진다. 각각의 줄에는 두 자연수 A와 B가 공백 하나를 사이로 두고 주어진다.

출력형식

각각의 테스트 케이스마다 순서대로, 스위치를 눌러야 하는 최소 횟수를 한 줄에 하나씩 출력한다.

입력예제1

2
1 2
9881 10724

출력예제1

5
11



2. 풀이

번호_매기기

  • 배열의 인덱스 값을 사용하여 번호별 전구의 on/off를 1과 0을 사용하여 7자리 문자열로 만들어줬다.

    • 그림처럼 array[8]에는 8의 전구 on/off를 나타낸 1101011이 저장되어 있다.
  • A와 B를 padStart()를 사용하여 5자리로 만들되, 앞에서부터 빈 자리가 있으면 _으로 채워줬다.

    • 이번에 padStart()라는 함수를 처음 사용해 봤는데, 이 함수가 생각나지 않을 때는 5 - A의길이를 이용해서 5자리로 만들어도 된다.
  • A와 B의 길이가 모두 5이므로 for문으로 5번 돌면서 각 자릿수를 비교한다.

    • 값이 다르다면 numbers 배열을 이용하여 스위치를 눌러야 하는 횟수를 증가시킨다.
    • _와 숫자를 비교하게 된다면 numbers 배열에서 해당 숫자값을 인덱스로 하는 값을 찾아, 그 값에서 1의 개수를 cnt에 더해준다.
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let array = []; // 입력값 담을 배열

const numbers = [
  "1110111",
  "0010010",
  "1011101",
  "1011011",
  "0111010",
  "1101011",
  "1101111",
  "1110010",
  "1111111",
  "1111011",
];

rl.on("line", (line) => {
  let input = line.split(" ");
  array = [...array, ...input];
}).on("close", () => {
  for (let i = 0; i < array[0]; i++) {
    let cnt = 0; // 스위치 눌러야 하는 횟수
    
    let from_num = array[i * 2 + 1].padStart(5, "_");
    let to_num = array[i * 2 + 2].padStart(5, "_");

    for (let j = 0; j < 5; j++) {
      if (from_num[j] === to_num[j]) continue; // 같은 위치의 값이 같으면 pass

      // 둘 중 하나의 자릿수가 "_"라면
      // numbers에서 다른 한 쪽의 값을 인덱스로 하는 값의 1의 개수만큼 cnt에 더해주기
      if (from_num[j] === "_")
        cnt += numbers[to_num[j]].split("").filter((e) => e === "1").length;
      if (to_num[j] === "_")
        cnt += numbers[from_num[j]].split("").filter((e) => e === "1").length;

      // 둘 다 숫자라면
      // numbers에서 해당 인덱스 값을 찾아서 하나하나 비교하여 다르면 cnt에 1추가
      if (from_num[j] !== "_" && to_num[j] !== "_") {
        numbers[from_num[j]].split("").map((e, i) => {
          if (e !== numbers[to_num[j]][i]) cnt += 1;
        });
      }
    }

    console.log(cnt);
  }
  process.exit();
});

이렇게 코드를 제출했더니 통과하긴 했다.
불필요한 요소가 있어서 배열이 아니라 객체로 풀어보고 싶은데 에러가 발생했다. 이 에러를 해결하면 코드를 다듬어서 추가로 올릴 것이다.



3. padStart(), padEnd()

ES2017부터 문자열에 padStart()padEnd() 메서드가 표준으로 제공된다.
다양한 용도로 활용할 수 있다는 장점이 있지만 구버전 웹브라우저에서는 호환성 문제가 있다는 단점이 있다.

3.1. padStart(자릿수, 채울문자)

  • 현재 문자열의 시작을 다른 문자열로 채워, 주어진 길이를 만족하는 새로운 문자열을 반환
  • 채워넣기는 대상 문자열의 시작(좌측)부터 적용
  • 자릿수가 현재 문자열의 길이보다 작다면 채워넣지 않고 그대로 반환
  • 채울문자가 너무 길어서 목표 문자열 길이를 초과한다면 좌측 일부를 잘라서 채움
  • 채울문자를 쓰지 않으면 기본값인 ""으로 채워짐
'abc'.padStart(10);         // "       abc"
'abc'.padStart(10, "foo");  // "foofoofabc"
'abc'.padStart(6,"123465"); // "123abc"
'abc'.padStart(8, "0");     // "00000abc"
'abc'.padStart(1);          // "abc"

3.2. padEnd(자릿수, 채울문자)

  • 현재 문자열에 다른 문자열을 채워, 주어진 길이를 만족하는 새로운 문자열을 반환
  • 채워넣기는 대상 문자열의 끝(우측)부터 적용
  • 자릿수가 현재 문자열의 길이보다 작다면 채워넣지 않고 그대로 반환
  • 자릿수가 너무 길어 목표 문자열 길이를 초과한다면 좌측 일부를 잘라서 넣음
  • 채울문자를 쓰지 않으면 기본값인 ""으로 채워짐
const str1 = 'Breaded Mushrooms';
console.log(str1.padEnd(25, '.'));
// Expected output: "Breaded Mushrooms........"

const str2 = '200';
console.log(str2.padEnd(5));
// Expected output: "200  "
profile
우당탕탕 FE 성장기

0개의 댓글