Paradox Simulation

728x90
반응형
반응형

프로그래머스에서 스킬 체크 테스트 level.1에 나온 알고리즘 문제가 있다.

코딩테스트 연습 - [1차] 비밀지도 | 프로그래머스 (programmers.co.kr)

 

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

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

programmers.co.kr

 

비밀지도라는 문제인데 다음과 같이 설명한다.

 

 

비밀지도

네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.

  1. 지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 "공백"(" ") 또는 "벽"("#") 두 종류로 이루어져 있다.
  2. 전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 "지도 1"과 "지도 2"라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
  3. "지도 1"과 "지도 2"는 각각 정수 배열로 암호화되어 있다.
  4. 암호화된 배열은 지도의 각 가로줄에서 벽 부분을 1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.

네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.

입력 형식

입력으로 지도의 한 변 크기 n과 2개의 정수 배열 arr1, arr2가 들어온다.

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

출력 형식

원래의 비밀지도를 해독하여 '#', 공백으로 구성된 문자열 배열로 출력하라.

입출력 예제

매개변수값

n 5
arr1 [9, 20, 28, 18, 11]
arr2 [30, 1, 21, 17, 28]
출력 ["#####","# # #", "### #", "# ##", "#####"]

매개변수값

n 6
arr1 [46, 33, 33 ,22, 31, 50]
arr2 [27 ,56, 19, 14, 14, 10]
출력 ["######", "### #", "## ##", " #### ", " #####", "### # "]

 

 

문제를 보고 해결할 때 다음과 같이 생각했다.

 

1. String[] 형태로 return 하지만, 좀 더 익숙한 List<String> 형으로 반환해보자
2. arr1, arr2 만큼 돌아야 하는데 주어진 n 값은 배열의 크기, 즉 한 줄의 최대 가로 사이즈를 말한다.
3. 바이너리 형식으로 바꾼다면 AND 연산자를 사용해야 + 형태로 더해지는 것이 아닌, 문제 요구사항처럼 출력 값이 나오도록 만들자
4. 만약 맨 앞이 0이라면 (5 글자면 00001 이 아닌, 1로 나온다고 생각한다.) 1 같은 경우 "    #" 이 아닌 "#"으로 나오겠네

 

 

우선 해답은 아래같이 만들었다.

 

import java.util.*;
class Solution {
    public List<String> solution(int n, int[] arr1, int[] arr2) {
        List<String> answer = new ArrayList<String>();
        String temp = "";
        for (int i=0; i<n; i++){
            temp = Integer.toBinaryString(arr1[i]|arr2[i]);
            if (temp.length() < n){
                temp = String.format("%" + n + "s", temp);
            }
            temp = temp.replaceAll("1", "#");
            temp = temp.replaceAll("0", " ");
            answer.add(temp);
        }
        return answer;
    }
}

 

왜 이렇게 만들었는지 한 줄 한 줄씩 설명을 하도록 해보겠다.

 

List<String> answer = new ArrayList<String>();

 

List<String> 같은 형태의 경우, add, get, ... 등등..

배열의 경우 크기를 한정지어서 사용해야 한다.

하지만, 한정적일 때보단 유동적으로 만들어야 할 때가 많았던 경험이 있었다.

그때 생각해낸 것이 String[] 인 배열 형보단, List<String> 형태로 String 값을 받아내지만, 유동적으로 사용하기 위해서 List<String>을 사용했다.

 

또한 결과적으로 나온 값을 answer.add(temp);

이 부분에서 temp에 나온 string 값을 answer List형에 넣어줌으로써 ( .add사용) 답을 반환시켰다.

 

2023.02.05 - [프로그래밍/JAVA 프로그래밍] - Java - List 클래스

 

temp = Integer.toBinaryString(arr1[i]|arr2[i]);

temp라는 스트링 형 안에 이진수로 만들어낸 숫자 값을 AND 연산하기 위해서 만들었다.

AND 연산은 연산해야 하는 값이 둘 중에 하나가 1이거나 둘 다 1일 때 1을 반환하게 된다.

 (쉽게는 0 AND 0 = 0, 1 AND 0 or 0 AND 1 = 1, 1 AND 1 = 1)

즉, 문제에서 요구하는 것 중에 9와 30을 AND 연산하게 된다면 다음과 같은 연산이 발생한다.

01001 AND 11110 = 11111

 

Integer.toBinaryString에 대해서는 아래와 같이 설명하겠다.

 

2023.02.01 - [프로그래밍/JAVA 프로그래밍] - Java - Integer, string to int

 

if (temp.length() < n) {
    temp = String.format("%" + n + "s", temp);
}
    temp = temp.replaceAll("1", "#");
    temp = temp.replaceAll("0", " ");

만약 맨 앞이 1이 아닌 0일 경우엔?

첫 번째 조건에서 arr1[0] 의 값은 9이다.

9를 2진수로 변환하게 되면 01001이 아닌 1001이 나오게 되고, AND 연산 이후 5자리 숫자가 되지 못한다면, 0 값은 공백이 되어버린다.

즉, 01000의 변환이 " #   " 이 되어야 하는데, "#   " 이 된다.

 

이제 슬슬 차이점이 보일 거라 생각한다.

앞에 0을 " "으로, 1을 "#"으로 변환해야 하는 과정에서 맨 앞의 0이 생략이 되어버리니까 공백으로조차 두지 못하는 점이 발생한다.

 

이를 방지하기 위해선 String.format 형을 사용했다.

 

String.format 같은 경우 여러 가지로 이용되지만, 그중 값에 앞부분에 패딩을 채워 넣기 위해 사용되기도 한다.

String.format(% + 숫자 + s , 값);

 

또한 String 형의 기본적인 기능으로 replaceAll이라는 기능이 있다.

해당 기능은 변환하고 싶은 대상을 변환할 문자열로 사용하게 되어 있다.

string.replaceAll(변환하고 싶은 문자열, 변환해야 하는 문자열);

 

그렇게 된다면 11111같은경우에도 #####으로 표현이 가능하니까.

 

 

 

해당 문제를 풀고 결과는 다음과 같이 나왔다.

 

채점을 시작합니다.
정확성 테스트
테스트 1 〉 통과 (7.92ms, 80.1MB)
테스트 2 〉 통과 (10.45ms, 79.5MB)
테스트 3 〉 통과 (7.30ms, 77.1MB)
테스트 4 〉 통과 (8.40ms, 83.7MB)
테스트 5 〉 통과 (8.31ms, 74.3MB)
테스트 6 〉 통과 (7.55ms, 77MB)
테스트 7 〉 통과 (9.02ms, 78.5MB)
테스트 8 〉 통과 (8.41ms, 74.6MB)
채점 결과
정확성: 50.0
효율성: 0.0

 

합계: 50.0 / 50

 

 

728x90
반응형
250x250
반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band