[프로그래머스] Lv.1 [1차] 비밀지도 JavaScript

Janet·2023년 3월 2일
0

Algorithm

목록 보기
43/314

문제 설명

비밀지도

네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.

  1. 지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 "공백"(" ") 또는 "벽"("#") 두 종류로 이루어져 있다.
  2. 전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 "지도 1"과 "지도 2"라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
  3. "지도 1"과 "지도 2"는 각각 정수 배열로 암호화되어 있다.
  4. 암호화된 배열은 지도의 각 가로줄에서 벽 부분을 1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.

http://t1.kakaocdn.net/welcome2018/secret8.png

네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.

입력 형식

입력으로 지도의 한 변 크기 n 과 2개의 정수 배열 arr1arr2가 들어온다.

  • 1 ≦ n ≦ 16
  • arr1arr2는 길이 n인 정수 배열로 주어진다.
  • 정수 배열의 각 원소 x를 이진수로 변환했을 때의 길이는 n 이하이다. 즉, 0 ≦ x ≦ 2 - 1을 만족한다. n

출력 형식

원래의 비밀지도를 해독하여 '#'공백으로 구성된 문자열 배열로 출력하라.

입출력 예제

매개변수
n5
arr1[9, 20, 28, 18, 11]
arr2[30, 1, 21, 17, 28]
출력["#####","# # #", "### #", "# ##", "#####"]
매개변수
n6
arr1[46, 33, 33 ,22, 31, 50]
arr2[27 ,56, 19, 14, 14, 10]
출력["######", "### #", "## ##", " #### ", " #####", "### # "]

해설 보러가기


문제풀이

💡 문제풀이 과정

  • 사실 이 문제의 의도는 비트 연산(Bitwise Operation)을 잘 다룰 수 있는지 묻는 것이라고 한다. (카카오 해설 참고) 따라서 답안 1번은 다른 분의 풀이를 참고하여 비트 연산자인 '|' (OR: 조건 연산자)와 padStart()정규 표현식을 이용한 풀이를 볼 수 있었다. 두 개의 정수 배열을 toString()을 통해 2진수로 변환한 값들을 비트의 논리합을 하는 |연산자(조건 연산자 OR)를 사용하여 0 혹은 1의 결과물을 출력할 수 있다.
  • | 연산자는 0과 0인 경우에는 ‘0’, 나머지(1과 0, 0과 1, 1과 1)의 경우에는 ‘1’을 출력한다.
    • 따라서 만약 a = 10100, b = 00001 인 경우, 10101이라는 결과가 나온다.
1 0 1 0 0 // a
0 0 0 0 1 // b
===================
1 0 1 0 1 // result
  • padStart()padEnd()
    • 입력할 문자열의 최대 길이를 지정하고, 그 길이만큼 원하는 문자열을 채워서 입력할 수 있는 메소드이다.
    • 첫 번째 파라미터로 maxLength (문자열의 길이)를 받고, 두 번째 파라미터로는 채워줄 문자열을 받는다(2번째 파라미터 미입력시에는 빈 공백으로 문자열을 채운다)
String.prototype.padStart(maxLength, ?fillString);
String.prototype.padEnd(maxLength, ?fillString);
    
const str = "패드";
console.log(str.padStart(5, 0)); // 000패드
console.log(str.padEnd(5, 0)); // 패드000
    
// 두 번째 인자 미입력 시, 공백으로 채워짐.
console.log(str.padStart(5)); //    패드
console.log(str.padEnd(5)); // 패드

  • 답안 2번은 내가 정규 표현식없이 풀이한 내용이다. 코드 길이의 차이…

✅ 답안 #1 - 비트 연산자(bitwise operator)와 정규표현식 활용

function solution(n, arr1, arr2) {
  return arr1.map((v, i) =>
    (v | arr2[i])
      .toString(2)
      .padStart(n, 0)
      .replace(/0/g, " ")
      .replace(/1/g, "#")
  );
}

✅ 답안 #2

function solution(n, arr1, arr2) {
  let map1 = [];
  let map2 = [];
  let sumArr = [];
  let answer = [];

  arr1.map((v) => {
    const num = v.toString(2);
    map1.push(num.length < n ? "0".repeat(n - num.length) + num : num);
  });
  map1 = map1.join("").split("");

  arr2.map((v) => {
    const num = v.toString(2);
    map2.push(num.length < n ? "0".repeat(n - num.length) + num : num);
  });
  map2 = map2.join("").split("");

  map1.map((v, i) =>
    Number(map1[i]) || Number(map2[i]) === 1 ? sumArr.push("#") : sumArr.push(" ")
  );

  for (let j = 0; j < sumArr.length; j += n) {
    answer.push(sumArr.slice(j, j + n).join(""));
  } // 값을 5개씩 묶어 잘라주고, join으로 5개 값을 한 값으로 붙이기
  return answer;
}
profile
😸

0개의 댓글