https://programmers.co.kr/learn/courses/30/lessons/17681
[문제]
네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.
- 지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 "공백"(" ") 또는 "벽"("#") 두 종류로 이루어져 있다.
- 전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 "지도 1"과 "지도 2"라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
- "지도 1"과 "지도 2"는 각각 정수 배열로 암호화되어 있다.
- 암호화된 배열은 지도의 각 가로줄에서 벽 부분을 1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.
네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.
[입력 조건]
입력으로 지도의 한 변 크기 n 과 2개의 정수 배열 arr1, arr2가 들어온다.
- 1 ≦ n ≦ 16
- arr1, arr2는 길이 n인 정수 배열로 주어진다.
- 정수 배열의 각 원소 x를 이진수로 변환했을 때의 길이는 n 이하이다. 즉, 0 ≦ x ≦ 2^(n - 1)을 만족한다.
[코드]
class Solution {
public String[] solution(int n, int[] arr1, int[] arr2) {
String[] answer=new String[n];
/*
* 두 개의 비밀지도 각 줄마다 10진수의 값을 2진수로 변환 후
* 두 2진수의 각 자리를 비교하여 공백 또는 #을 저장한다.
* 이러한 과정을 주어진 비밀지도의 길이인 n만큼 반복한다.
*/
for(int i=0;i<n;i++) {
// 각 배열의 10진수 값을 2진수로 변환한다.
int[] arr1Binary=makeBinary(n,arr1[i]);
int[] arr2Binary=makeBinary(n,arr2[i]);
String str="";
/*
* 2진수로 변환한 자릿수의 값이 모두 0일 경우에만 공백 저장
* 둘 중 하나의 값이라도 1일 경우에는 '#' 저장
*/
for(int j=0;j<arr1Binary.length;j++) {
if(arr1Binary[j]==0&&arr2Binary[j]==0) {
str+=" ";
}
else
str+="#";
}
// 한 줄이 처리가 끝나면 결과 값 answer 배열에 저장
answer[i]=str;
}
return answer;
}
// 10진수를 2진수로 변환하는 함수
public int[] makeBinary(int n,int num) {
int[] result=new int[n];
int number=num;
for(int i=n-1;i>=0;i--) {
result[i]=number%2;
number/=2;
}
return result;
}
}
[고찰]
문제를 다 풀고난 후 좀 더 효율적으로 코드를 구성하는 방법이 있지는 않을까 생각해 다른 사람들의 포스팅을 열람해봤다. 그 결과 이번 문제는 라이브러리로 제공하는 함수를 사용하면 더 쉽게 해결할 수 있다는 것을 알았다. 아래 코드가 해당 부분이다.
class Solution {
public String[] solution(int n, int[] arr1, int[] arr2) {
String[] answer = new String[n];
for(int i =0;i<n;i++){
// arr1과 arr2의 원소들을 이진수로 바꾼 뒤, or 비트 논리연산 수행.
String str=Integer.toBinaryString(arr1[i] | arr2[i]);
// 5자리의 문자열 형태로 포맷변경, 5자리가 안되는 이진수의 나머지는 공백으로 채운다.
str = String.format("%"+n+"s",str);
// 1->#, 0->공백 으로 바꾼다.
str = str.replaceAll("1" , "#");
str = str.replaceAll("0" , " ");
// 한 줄 완성.
answer[i] = str;
}
return answer;
}
}
위 코드는 10진수를 2진수로 변경해주는 Integer.toBinartString() 함수를 사용하여 풀이한 방법이다. 또한 2진법으로 바꾸는 동시에 or 비트 논리연산을 수행하여 각 자릿수가 0인지 1인지 판별해야 하는 if문 또한 필요하지 않아졌다. 이런 방법을 사용하면 따로 변경 함수와 판별문을 만들어주지 않아도 돼 훨씬 코드가 간결해 진 것을 확인할 수 있다.
하지만 위 함수를 몰랐다 하더라도 직접 구현하는 방법으로 풀이하여 충분히 정답 처리를 받을 수 있다.
'프로그래머스' 카테고리의 다른 글
[프로그래머스_Level1] 신규 아이디 추천_2021 카카오 신입 공채 (0) | 2021.07.19 |
---|---|
[프로그래머스_Level1] 폰켓몬 (0) | 2021.07.19 |
[프로그래머스_Level1] 체육복 (0) | 2021.07.18 |
[프로그래머스_Level1] 완주하지 못한 선수 (0) | 2021.07.18 |
[프로그래머스_Level1] 음양 더하기 (0) | 2021.07.18 |