프로그래머스 2018 KAKAO BLIND RECRUITMENT Level 1 문제 비밀 지도를 Java를 이용해 풀어보았다.
비트 연산자를 이용해 풀도록 낸 문제겠다 싶었지만 내가 그리 익숙하지 않기 때문에 실제 시험 때 시간에 쫓기며 푼다는 가정 하에 그냥 내가 익숙한 풀이로 풀었다.
문제 링크 첨부한다.
https://programmers.co.kr/learn/courses/30/lessons/17681
비트 연산자를 이용해 바람직하게 푸는 것이 아닌 내 무식한 풀이는 다음과 같다.
주어진 int[] arr1
과 int[] 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);
}
}
위에서 구한 binArr1
과 binArr2
를 대조하며 이제 실제 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진수로 변환해야 하는 문제가 나온다면 이렇게 풀어야지.