본문 바로가기
알고리즘 문제/프로그래머스

[프로그래머스 - Java] 비밀지도(2018 KAKAO BLIND RECRUITMENT [1차])

by 건복치 2020. 5. 3.
반응형

링크

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

1. 처음 코드

처음에 1차원적으로 생각한대로 구현했다.

너무 길고 불필요한 코드도 많다고 생각이 든다.

하나하나 사서 고생하는 느낌

 

*십진수 이진수로 변환할 때는 toBinaryString() 사용

 

class Solution {
  public String[] solution(int n, int[] arr1, int[] arr2) {
      String[] answer = new String[n];
    
      String[] temp1 = new String[n];
      String[] temp2 = new String[n];
      int[][] map = new int[n][n];
      
      //2진수 구하기
      convertToBinary(n, arr1, temp1);
      convertToBinary(n, arr2, temp2);
      
      //비밀지도 구성하기
      makeMap(map, temp1);
      makeMap(map, temp2);
      
      //비밀지도에 따른 정답 구성하기
      getAnswer(answer, map);
      
      return answer;
  }
    
    //배열의 값 2진수로 만들기 
    public void convertToBinary(int n, int[] arr, String[] temp) {
        for(int i = 0; i < arr.length; i++) {
            String binaryString = Integer.toBinaryString(arr[i]);
            int gap = n - binaryString.length();
             while(gap != 0) { //이진수 길이가 n보다 모자랄 경우 앞에 0을 붙여줌
                  binaryString = "0".concat(binaryString);
                  gap--;
          }
            temp[i] = binaryString;
        }
    }
    
    //비밀지도에 얻어진 2진수 값 넣어서 전체 비밀지도 만들기
    public void makeMap(int[][] map, String[] temp) {
        int n = map.length;
        for(int i = 0; i < n; i++) {
            String str = temp[i];
            for(int j = 0; j < n; j++) {
                int value = Integer.parseInt(str.charAt(j) + "");
                if(value == 1) { //1, 벽일 경우 무조건 벽
                    map[i][j] = 1;
                } else { //0, 공백일 경우 
                    if(map[i][j] != 1) //벽이 아닌 경우에만 공백
                        map[i][j] = 0;
                }
            }
        }
    }
    
    //비밀지도의 0과 1로 벽과 공백 구분해 answer에 저장
    public void getAnswer(String[] answer, int[][] map) {
        int n = map.length;
        
        for(int i = 0; i < n; i++) {
            StringBuilder sb = new StringBuilder();
            for(int j = 0; j < n; j++) {
                if(map[i][j] == 1) {
                    sb.append("#");
                } else {
                    sb.append(" ");
                }
            }
            answer[i] = sb.toString();
            sb.setLength(0);
        }
    }
    
}

 

2. 수정코드

다른 사람의 풀이를 보면서 다시 코드를 수정했다.

아는 만큼 엄청 줄일 수 있는...ㄷㄷ

 

원래는 arr1, arr2 따로 2진수 값으로 만들고 이를 다시 합치면서 map이라는 비밀지도를 만들었는데

그럴필요 없이 OR연산으로 한 번에 계산이 가능하다.

그래서 바로 2진수로 바꾸어 OR연산 시켜서 answer 배열에 담는다.

- OR연산 : 하나라도 1(참)이면 1, 모두 0(거짓)이면 0

 

 

answer에 0과 1로 저장되어 있는 것을 문제가 원하는 대로 '#'과 ' '공백을 이용해 출력하면 끝.

근데 이진수로 변환했을 경우 숫자의 길이가 n길이와 맞지 않을 수 있기 때문에 format 함수를 이용해 길이를 맞춰준다.

- %s : 해당 위치의 스트링을 대체한다.

- %ns : 숫자 n만큼 좌측에 공백을 채워 문자열 길이를 만든다.(숫자보다 문자열 길이가 긴 경우에는 그대로)

replace 함수를 이용해 #과 공백으로 치환

 

class Solution {
  public String[] solution(int n, int[] arr1, int[] arr2) {
      String[] answer = new String[n];
      
      for(int i = 0; i < n; i++) { 
          answer[i] = Integer.toBinaryString(arr1[i] | arr2[i]);
      }
      
      for (int i = 0; i < n; i++) {
          answer[i] = String.format("%" + n + "s", answer[i]);
          answer[i] = answer[i].replaceAll("1", "#");
          answer[i] = answer[i].replaceAll("0", " ");
      }
      
      return answer;
  }   
}
반응형

댓글