프로그래머스-2018 KAKAO BLIND RECRUITMENT ( 비밀 지도 by Java )

Flash·2022년 2월 6일
0

Programmers-Algorithm

목록 보기
17/52
post-thumbnail

비트 연산자? 직접 구현?

프로그래머스 2018 KAKAO BLIND RECRUITMENT Level 1 문제 비밀 지도Java를 이용해 풀어보았다.
비트 연산자를 이용해 풀도록 낸 문제겠다 싶었지만 내가 그리 익숙하지 않기 때문에 실제 시험 때 시간에 쫓기며 푼다는 가정 하에 그냥 내가 익숙한 풀이로 풀었다.

문제 링크 첨부한다.
https://programmers.co.kr/learn/courses/30/lessons/17681


무식하게 풀기

비트 연산자를 이용해 바람직하게 푸는 것이 아닌 내 무식한 풀이는 다음과 같다.

주어진 int[] arr1int[] arr2를 직접 주어진 자릿수에 맞는 이진수로 만드는 작업을 먼저 한다. Integer.toBinaryString() 메소드를 쓴 후에 자릿수가 부족하면 앞에다 0을 붙여주는 방식이다.

이를 코드로 표현하면 다음과 같다.

void createBinString(int n, int idx, int[] arr){
        ArrayList<String> binArr = new ArrayList<>();

        for(int a: arr) {
            String tmp = Integer.toBinaryString(a);
            while(tmp.length()<n)
                tmp = "0" + tmp;
            binArr.add(tmp);
        }

        if(idx==1){
            binArr1 = new ArrayList<>(binArr);
            Collections.copy(binArr1, binArr);
        }
        else{
            binArr2 = new ArrayList<>(binArr);
            Collections.copy(binArr2, binArr);
        }
    }

위에서 구한 binArr1binArr2를 대조하며 이제 실제 map을 구해보자.

각 줄마다 한 자리씩 두 지도를 비교해서, 둘 다 0이면 " "를 붙이고 아니면 "#"를 붙이자.

이를 코드로 표현하면 다음과 같다.

void getMap(int n){
        for(int i=0; i<n; i++){
            String s1 = binArr1.get(i);
            String s2 = binArr2.get(i);
            String res = "";

            for(int j=0; j<n; j++){
                char c1 = s1.charAt(j);
                char c2 = s2.charAt(j);
                if(c1=='0' && c2=='0') // 둘 다 공백이면
                    res += " ";
                else                   // 둘 중 하나라도 벽이면
                    res += "#";
            }
            map.add(res);
        }
    }

그럼 우리가 원하는 실제 지도를 다 구했다! List를 배열로 바꿔주는 작업만 하면 된다.

아래는 내가 제출한 전체 코드다.

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;

public class SecretMap {
    static ArrayList<String> binArr1 = new ArrayList<>();
    static ArrayList<String> binArr2 = new ArrayList<>();
    static ArrayList<String> map = new ArrayList<>();

    static String[] solution(int n, int[] arr1, int[] arr2) {
        createBinString(n, 1, arr1);
        createBinString(n, 2, arr2);
        getMap(n);
        String[] answer = map.toArray(new String[n]);

        return answer;
    }

    static void createBinString(int n, int idx, int[] arr){
        ArrayList<String> binArr = new ArrayList<>();

        for(int a: arr) {
            String tmp = Integer.toBinaryString(a);
            while(tmp.length()<n)
                tmp = "0" + tmp;
            binArr.add(tmp);
        }

        if(idx==1){
            binArr1 = new ArrayList<>(binArr);
            Collections.copy(binArr1, binArr);
        }
        else{
            binArr2 = new ArrayList<>(binArr);
            Collections.copy(binArr2, binArr);
        }
    }

    static void getMap(int n){
        for(int i=0; i<n; i++){
            String s1 = binArr1.get(i);
            String s2 = binArr2.get(i);
            String res = "";

            for(int j=0; j<n; j++){
                char c1 = s1.charAt(j);
                char c2 = s2.charAt(j);
                if(c1=='0' && c2=='0') // 둘 다 공백이면
                    res += " ";
                else                   // 둘 중 하나라도 벽이면
                    res += "#";
            }
            map.add(res);
        }
    }

    public static void main(String args[]) throws IOException {
        BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(System.out));
        int n = 5;
        int[] arr1 = {9, 20, 28, 18, 11};
        int[] arr2 = {30, 1, 21, 17, 28};
        for(String s: solution(n,arr1,arr2))    bfw.write(s + "\n");
        bfw.close();
    }
}

비트 연산자

문제를 풀고나서 다른 사람들의 풀이를 보며 가장 실전에서 바로 생각해서 쓸 수 있고 적당한 수준의 기술을 쓴 풀이는 다음과 같았다.

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

          for (int i = 0; i < n; i++) {
              container[i] = arr1[i] | arr2[i];
          }

          String[] answer = new String[n];

          for (int i = 0; i < n; i++) {
              String ans = "";
              int remainder = container[i];

              for (int j = 0; j < n; j++) {                               
                  if(remainder%2 == 1) { ans = "#" + ans; } 
                  else { ans = " " + ans; }
                  remainder = remainder/2;
              }

              answer[i] = ans;
          }           
          return answer;
  }
}

먼저 비트 연산자를 이용해 각 줄마다의 10진수 결과를 구하고, 2로 나눈 나머지에 따라 "#"인지 " "인지 판별하는 위의 풀이가 가장 실전에 적합하지 않을까 싶었다. 다음에 또 10진수를 2진수로 변환해야 하는 문제가 나온다면 이렇게 풀어야지.

profile
개발 빼고 다 하는 개발자

0개의 댓글