개발 일기

프로그래머스 레벨1 [1차] 비밀지도 (JAVA) 본문

알고리즘/programmers

프로그래머스 레벨1 [1차] 비밀지도 (JAVA)

dev-jo 2021. 7. 1. 01:22

 

오늘은 야근을 했다..ㅠ.ㅠ

 

아주 사소한 거 때 매 자꾸 에러가 난 거였다.. 암튼..

 

오늘도 한 문제를 풀어본다.

 

모든 코드는 GitHub 올려놓았다.

 

오늘 풀 문제!

 

https://programmers.co.kr/learn/courses/30/lessons/17681

 

코딩테스트 연습 - [1차] 비밀지도

비밀지도 네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다

programmers.co.kr

 

이 문제는 배열의 수를 2진법으로 만들고

 

1일 경우 #을 추가해주는 거다.. 결국

 

2개의 배열의 값을 2진법으로 만들고..

 

비교를 해주고  1일 경우 # 을 추가해주고 아닐 경우 공백을 추가하면 된다.

 

public static String[] solution(int n, int[] arr1, int[] arr2) {
        String[] answer = new String[n];

        for (int i = 0; i < n; i++) {

            StringBuilder firstBuilder = new StringBuilder();
            StringBuilder secondBuilder = new StringBuilder();

            while (arr1[i] > 0) {
                firstBuilder.insert(0, arr1[i] % 2);
                arr1[i] = arr1[i] / 2;
            }

            while (arr2[i] > 0) {
                secondBuilder.insert(0, arr2[i] % 2);
                arr2[i] = arr2[i] / 2;
            }

            if (firstBuilder.length() < n) {
                int range = n - firstBuilder.length();
                for (int j = 0; j < range; j++) {
                    firstBuilder.insert(0, "0");
                }
            }

            if (secondBuilder.length() < n) {
                int range = n - secondBuilder.length();

                for (int j = 0; j < range; j++) {
                    secondBuilder.insert(0, "0");
                }
            }

            StringBuilder result = new StringBuilder();
            for (int j = 0; j < n; j++) {
                if (String.valueOf(firstBuilder.charAt(j)).equals("1") || String.valueOf(secondBuilder.charAt(j)).equals("1")) {
                    result.append("#");
                } else {
                    result.append(" ");
                }
            }

            answer[i] = result.toString();

        }

        return answer;
    }

 

 

처음 푼 코드는 이러했다.. 각각 2진수로 만들어주고

 

길이가 n 보다 작을 경우 앞에 0을 붙여줬다

 

앞에 0을 붙인 이유는 10진수 9를 2 진수로 변환하면

 

1001이다.

 

하지만 문제 예시에는 01001로 표시되어있다.

 

즉 n 만큼의 길이를 맞춰줘야 한다는 거다.

 

그래서 builder.insert로 앞에 0을 추가해주고

 

마지막에 비교해주었다.

 

문제를 풀고 너무 코드가 길어 보이길래 

 

문제를 다시 읽고 풀어보았다.

 

class Solution {
    public String[] solution(int n, int[] arr1, int[] arr2) {
        String[] answer = new String[n];

        for(int i=0; i<n; i++) {
            StringBuilder builder = new StringBuilder();
            for(int j=0; j<n; j++) {

                if(arr1[i] % 2 == 1 || arr2[i] % 2 == 1) {
                   builder.insert(0, "#");
                } else {
                    builder.insert(0, " ");

                }
                arr1[i] /= 2;
                arr2[i] /= 2;
            }
            answer[i] = builder.toString();
        }


        return answer;
    }
}

 

간단해졌다.

 

이문제의 핵심은

 

정수 배열의 각 원소 x를 이진수로 변환했을 때의 길이는 n 이하이다. 즉, 0 ≦ x ≦ 2n - 1을 만족한다.

 

즉 배열의 수를 이진수로 변환해도 n보다 작다는 거다

 

그럼 전체 배열 값을 같이 꺼내기 위해

 

for를  n 만큼 돌리고

 

각배 열의 n번쨰 값을 2진수로 만든다. n만큼

 

n만큼 하는 이유는 이진수로 변환했을 때 n이하고

 

n보다 작을 경우 0을 붙여줘야 하기 때문

 

바로 n보다 작은거는 공백을 넣어줄수 있다!

 

그리고 코드는..

 

arr1[i] % 2 == 1 || arr2[i] % 2 == 1

 

둘 중 하나라도 이진수로 변환했을 때 1이라면 #을 추가

 

아니라면 공백을 추가하고

 

값을 바로 넣어준다..!

 

끝!

 

문제만 잘 읽으면 짧게 할 수 있는 문제다..!