본문 바로가기
Developer/Algorithm

프로그래머스 코딩테스트 연습 Level 2 - 이진 변환 반복하기 (JavaScript)

by roqkfrlfhr 2022. 7. 19.

프로그래머스 코딩테스트 연습 Level 2 - 이진 변환 반복하기 (JavaScript)

 

Programmers(프로그래머스)의 코딩테스트 연습문제 Level 2 중,

[이진 변환 반복하기] 문제를 JavaScript를 사용하여 해결해 보도록 하겠습니다.

 

문제

문제 설명

0과 1로 이루어진 어떤 문자열 x에 대한 이진 변환을 다음과 같이 정의합니다.

  1. x의 모든 0을 제거합니다.
  2. x의 길이를 c라고 하면, x를 "c를 2진법으로 표현한 문자열"로 바꿉니다.

예를 들어, x = "0111010"이라면, x에 이진 변환을 가하면 x = "0111010" -> "1111" -> "100" 이 됩니다.

0과 1로 이루어진 문자열 s가 매개변수로 주어집니다. s가 "1"이 될 때까지 계속해서 s에 이진 변환을 가했을 때, 이진 변환의 횟수와 변환 과정에서 제거된 모든 0의 개수를 각각 배열에 담아 return 하도록 solution 함수를 완성해주세요.

 

제한사항

  • s의 길이는 1 이상 150,000 이하입니다.
  • s에는 '1'이 최소 하나 이상 포함되어 있습니다.

 

입출력 예

s result
"110010101001" [3,8]
"01110" [3,3]
"1111111" [4,1]

 

입출력 예 설명

입출력 예 #1

  • "110010101001"이 "1"이 될 때까지 이진 변환을 가하는 과정은 다음과 같습니다.
회차 이진 변환 이전 제거할 0의 개수 0 제거 후 길이 이진 변환 결과
1 "110010101001" 6 6 "110"
2 "110" 1 2 "10"
3 "10" 1 1 "1"
  • 3번의 이진 변환을 하는 동안 8개의 0을 제거했으므로, [3,8]을 return 해야 합니다.

 

입출력 예 #2

  • "01110"이 "1"이 될 때까지 이진 변환을 가하는 과정은 다음과 같습니다.
회차 이진 변환 이전 제거할 0의 개수 0 제거 후 길이 이진 변환 결과
1 "01110" 2 3 "11"
2 "11" 0 2 "10"
3 "10" 1 1 "1"
  • 3번의 이진 변환을 하는 동안 3개의 0을 제거했으므로, [3,3]을 return 해야 합니다.

 

입출력 예 #3

  • "1111111"이 "1"이 될 때까지 이진 변환을 가하는 과정은 다음과 같습니다.
회차 이진 변환 이전 제거할 0의 개수 0 제거 후 길이 이진 변환 결과
1 "1111111" 0 7 "111"
2 "111" 0 3 "11"
3 "11" 0 2 "10"
4 "10" 1 1 "1"
  • 4번의 이진 변환을 하는 동안 1개의 0을 제거했으므로, [4,1]을 return 해야 합니다.

 

 

작성한 답

solution.js

function solution(s) {
    let convertNum = 0, deleteZeroNum = 0;
    
    while (s !== '1') {
        convertNum++;
        const zeroMatch = s.match(/0/g);
        const zeroNum = zeroMatch ? zeroMatch.length : 0;
        deleteZeroNum += zeroNum;
        s = (s.length - zeroNum).toString(2);
    }
    
    return [convertNum, deleteZeroNum];
}

 

설명

이진 변환의 횟수를 저장할 변수 convertNum과, 변환 과정에서 제거된 모든 0의 개수를 저장할 변수 deleteZeroNum을 0으로 초기화 합니다.

s가 '1' 이 될 때 까지 변환을 반복하라고 했으므로 while 문을 사용하여 s가 '1' 이 될 때 까지 반복을 시작하는데,

반복될 때 마다 변환 횟수 convertNum을 1씩 증가 시키고,

match(/0/g) 를 사용하여 s에 들어있는 '0' 을 전부 배열(zeroMatch)에 담고,

해당 배열이 null 이 아니라면 해당 배열의 길이를, null 이라면 0을 '0'의 개수를 담을 변수 zeroNum에 넣습니다.

deleteZeroNum에 '0'의 개수를 담고있는 zeroNum을 더함으로 제거된 0의 개수를 증가시킵니다.

그리고 s 문자열에서 '0' 을 제거한 문자열의 길이는 s의 길이에 zeroNum을 빼서 구할 수 있으므로,

s의 길이에 zeroNum을 뺀 값을 2진법으로 변환하여 s를 변경합니다.

 

위 과정을 모두 거치면 이진 변환 횟수와 변환 과정에서 제거된 모든 0의 개수를 구할 수 있으므로

해당 값을 배열에 순서대로 담아 반환하는 것으로 문제를 해결할 수 있습니다.

 

※ Programmers 에서는 지원되지 않아서 사용하지 못했지만,

ES2020 부터 사용가능한 Optional Chaining 기능을 사용하면 아래와 같이 작성할 수도 있습니다.

function solution(s) {
    let convertNum = 0, deleteZeroNum = 0;
    
    while (s !== '1') {
        convertNum++;
        const zeroNum = s.match(/0/g)?.length || 0;	// Optional Chaining 사용
        deleteZeroNum += zeroNum;
        s = (s.length - zeroNum).toString(2);
    }
    
    return [convertNum, deleteZeroNum];
}

 

 

도움이 되셨다면 공감, 댓글 부탁드립니다!

궁금하신 점이나 요청사항은 언제든지 말씀해주세요!

피드백도 언제나 환영입니다!

 

감사합니다.


댓글