[JavaScript] 비밀지도 Lv1

Date:     Last Updated:

문제명

문제 프로그래머스 FAQ 내용을 보니 카카오나 기업의 문제들은 저작권이 있으니 풀이를
github나 개인블로그에 올리지 말라고 되어 있어서 링크로 대체합니다.

출처: Programmers
비밀지도

문제의 이해

처음에 문제를 봤을 때는 좀 어려우려나? 생각했는데 다 읽고 보니 결과적으로 크게 어렵지는 않겠지? 라고 생각했는데, 솔직히 어려운 문제는 아니었는데 내 실력을 생각 못한 것이 오산이었다. 두개의 지도를 받아서 각 지도의 행의 값을 or연산해서 구해진 2진수 값으로 출력해주면 되겠지. 라고 생각했는데 그 과정이 쉽지는 않았다.

내가 생각한 풀이 방법

  1. 주어진 2개의 n * n 배열을 1행씩 or연산을 통해 만든 n * n 배열 하나를 만들어낸다.
  2. 만든 배열을 순회하면서 배열의 값이 1이면 #으로 0이면 빈 공간으로 만든 후 출력한다.

풀이

첫 번째 풀이

실패한 풀이 방법이 있었는데 이렇게 포스팅을 생각못하고 지워버렸다. 다음부터는 꼭 남겨놔서 포스팅하자.

위의 풀이방법처럼 뭔가 간단하게 될 줄 알았다. 근데 직접 코드를 짜보니까 풀이 방법의 1,2번의 내용이 1-1, 1-2 처럼 엄청 늘어지게 되었다. or연산을 통해서 만든 값의 첫 번째 문제점은 2진수 변환 부분 코드를 내가 직접 만들때는 소인수분해를 통해 만들다보니 주어지는 2진수의 방향이 반대로 되어서 전부 만든 후 뒤집어 줘야했었다. 두 번째 문제는 소인수분해를 통해서 2진수를 만들면 주어진 n보다 작은 자리 숫의 2진수가 나와서 n보다 작은 2진수면 작은 만큼 왼쪽에 0을 넣어줘야했다. 이런 것들을 모두 직접 구현하려고 하니 코드가 굉장히 길어졌다. 하지만 그래도 직접 구현해보자는 마음에 했는데, 지금도 후회하는 건 아니지만 시간도 꽤 잡아먹고 코드가 너무 방대해져버렸다. 그래서 포기하고 구글 검색을 통해서 js에서 10->2진수로 바꾸는 법을 검색하고 배열 <-> 문자열 변환을 하는 방법을 통해서 풀었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
function solution(n, arr1, arr2) {
    var answer = [];
    var orOperation = [];

    for(let i = 0; i < n; i++){
        orOperation[i] = arr1[i] | arr2[i];             //주어진 두 지도의 배열의 같은 위치 값을 or 연산해서 저장
        orOperation[i] = orOperation[i].toString(2);    //정확히 어떤 방식인지 js 제공해주는 건지는 모르겠지만 10진수를 20진수로 변환해줌.

        //지도의 가로 칸 갯수는 n개가 되어야 하는데 칸이 n개가 되지 못하는 수들이 있다.
        //이럴때 주어진 n보다 작은 문자열이라면 왼쪽에 적은 만큼 0을 더해준다.
        //입출력 예제 두 번째에서 arr1[4] | arr2[4] 를 하면 011111 or 001110 = 011111 10진수로는 31 그대로이다.
        //이때 n은 6이므로 2진수의 자리표현은 011111 로 되어야 하는데 가장 왼쪽의 0은 표현되지 않는다.
        //그래서 11111만 된다. 바로 아래 코드는 그걸 고쳐주기 위한 코드
        if(orOperation[i].length < n){
            orOperation[i] = zeroStringReturn(n, orOperation[i].length) + orOperation[i];
        }

        //js에서 문자열을 배열로 바꿔주는 방법
        orOperation[i] = [...orOperation[i]];

        //계산이 끝난 1과 0이 있는 배열을 출력 조건에 따라서 변환해준다.
        for(let j = 0; j < n; j++){
            if(orOperation[i][j] == '1'){
                orOperation[i][j] = '#';
            }
            else{
                orOperation[i][j] = ' ';
            }
        }

        //answer변수에 담아 리턴하기 위해
        //위에서 문자열->배열로 변환했던 것을 다시 문자열로 변환한다.
        //문자열로 변환하면 ,같은 것들도 모두 포함이 되기 때문에 
        //replace로 모두 제거 하는 부분이다.
        answer[i] = orOperation[i].toString().replace(/,/g,"");
    }

    return answer;
}

//주어진 count가 n보다 얼마나 작은지 판단해서 작은 만큼 0을 붙여서 문자열로 리턴해준다.
function zeroStringReturn(n, count){
    var string = '';
    for(let i = 0; i < n - count; i++){
        string += '0';
    }
    return string;
}

두 번째 풀이

첫 번째 풀이가 맘에 안들어서 좀 더 함수로 나눠서 푼건데 역시 다시 보니까 그닥 첫번째 코드보다 나은 게 없는 것 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
function binaryConversion(n, arr1, arr2){
    var binaryMap = [];
    var answer = [];
    
    for(let i = 0; i < n; i++){
        binaryMap[i] = arr1[i] | arr2[i];             //주어진 두 지도의 배열의 같은 위치 값을 or 연산해서 저장
        binaryMap[i] = binaryMap[i].toString(2);    //정확히 어떤 방식인지 js 제공해주는 건지는 모르겠지만 10진수를 20진수로 변환해줌.
        binaryMap[i] = zeroStringReturn(n, binaryMap[i]);
        answer[i] = mapPrint(n, binaryMap[i]);
    }
    return answer;
}

//주어진 count가 n보다 얼마나 작은지 판단해서 작은 만큼 0을 붙여서 문자열로 리턴해준다.
function zeroStringReturn(n, binaryArr){
    var string = '';
    
    if(binaryArr.length < n){
        for(let i = 0; i < n - binaryArr.length; i++){
            string += '0';
        }
    }
    
    return [...(string + binaryArr)];
}

function mapPrint(n, binaryArr){
    for(let j = 0; j < n; j++){
            if(binaryArr[j] == '1'){
                binaryArr[j] = '#';
            }
            else{
                binaryArr[j] = ' ';
            }
        }
        
    return binaryArr.toString().replace(/,/g,"");
}

function solution(n, arr1, arr2) {
    return binaryConversion(n, arr1, arr2);
}


Leave a comment