[Programmers Level 1] [1차]비밀지도 Javascript
문제정보
카카오 신입공채 1차 코딩테스트 문제라고 하네요!
레벨1이고... 문제 해설집을 열어보니 정답률이 무려 81.78%...근데도 꽤나 애먹었어요 나 어느정도로 못하는거냐고www
항상 그렇지만 이렇게 문제가 길면 읽는거 자체가 마음에 안드는것같아요
문제를 간단히 보면 이렇습니다.
지도 두개를 합친다 -> 지도 둘중 하나라도 1이 있으면 그건 벽이다.
근데 지도가 처음부터 완성된채로 주어지는게 아니라서 먼저 지도를 만드는 것부터 시작해야할것같네요
그러면
1. arr1 , arr2의 모든 요소를 2진수로 변환한다.
2. 2진수로 변환된 arr1과 arr2의 모든 요소를 탐색하면서
둘 중 하나라도 1이 있으면 "#"을 아니라면 " " 공백을 넣어준다.
근데 처음에는 그냥 2진수로 변환해서 풀면 되지않나? 싶었는데 공백이 문제가 되더라고요
예를 들어서 9의 경우 2진수로 변환하면 1001로 총 네개의 숫자를 가지는데
벽의 크기는 5인 경우 부족한만큼을 0으로 채워서 생각해야하기때문에
01001로 만들어서 문제를 풀어야했어요
처음에는 Array.from()으로 0을 채워주어야하나 했습니다만
구글링의 도움을 조금 받아서 해결했습니다.. 해결 방법은 후략할게요
예시
매개변수 값
n 5
arr1 [9, 20, 28, 18, 11]
arr2 [30, 1, 21, 17, 28]
출력 ["#####","# # #", "### #", "# ##", "#####"]
나의풀이
function solution(n, arr1, arr2) {
let answer = []
for(i=0; i < arr1.length ;i++ ) {
let first = arr1[i].toString(2).padStart(n,0)
let second = arr2[i].toString(2).padStart(n,0)
let counter = ''
for(j=0; j<first.length ; j++) {
if(first[j] == 1 || second[j] == 1) {
counter = counter + "#"
}
else counter = counter + " "
}
answer.push(counter)
}
return answer
}
for문을 중첩해서 문제를 풀었습니다.
얼마전에 읽은 알고리즘 책에는 문제를 이런식으로 풀면꼭 시간복잡도를 줄일 수 있는 다른 방안이 있는지생각해보라는 구절을 읽었는데 hmm...
padStart()
메서드는 현재 문자열의 시작을 다른 문자열로 채워, 주어진 길이를 만족하는 새로운 문자열을 반환합니다. 채워넣기는 대상 문자열의 시작(좌측)부터 적용됩니다.
구글링의 도움을 받아 사용한 padStart()메서드입니다.
문자열을 주어진 길이에 만족하도록 바꿔주고 문자열의 왼쪽부터 채워넣는 메서드네요
완전히 이 문제를 위한 메서드가 아닌가
하여튼 이걸 적용시켜주면
9.toString(2)를 하면 1001이지만
9.toString(2).padStart(5)를 하면 01001이 반환되겠네요
str.padStart(targetLength [, padString])
기본적인 문법은 이렇습니다.
padStart(원하는 길이 , 채울문자 )라고 보면 될듯..?
이제 공백을 0으로 치환한 2진수로 변환해주기는
let first = arr1[i].toString(2).padStart(n,0)
let second = arr2[i].toString(2).padStart(n,0)
이걸로 해결했고
맵을 두개로 합쳐서 비교하는 건 or 연산자를 이용하면 쉽게 해결할 수 있네요
다른사람의 풀이
var solution=(n,a,b)=>a.map((a,i)=>(a|b[i]).toString(2).padStart(n,0).replace(/0/g,' ').replace(/1/g,'#'))
비트연산자 | 를 이용한 풀이입니다.비트연산자라는거 자체를 거의 처음 알았네요..비트연산자 | 는 두 피연산자의 각 자리 비트의 값이 모두 0인 위치에 0을 반환합니다.
toString , padStart replace(정규표현식)은 다 뭔지 알겠는데
저 비트연산자가 어떻게 동작하는지 감이 잡히질 않았는데 콘솔로그 하나씩 찍어보니까 대략...
완전히 개소리같지만...
아래 예시를 보면 조금 이해가 갑니다.
5를 2진수로 보면 101
3을 2진수로 보면 11
저 5와 3의 자릿수를 하나하나 비교하면서 둘다 0인경우엔 0 하나라도 1인 경우엔 1을 넣어서
새로운 값을 반환하면
101
011
= 111
111을 2진수로 변환하면 7 이런식으로 값이 나오는거네요!!
뭐야 이러면 합치는 과정을 한번에 할 수 있군요
지식이 늘었습니다...