본문 바로가기
codingtest

[programmers] 저주의 숫자 3, 외계어 사전, 안전지대, 컨트롤 제트, 배열 원소의 길이

by 안자두 2023. 3. 12.

📝 [Lv0] 저주의 숫자 3

👀 문제 설명

3x 마을 사람들은 3을 저주의 숫자라고 생각하기 때문에 3의 배수와 숫자 3을 사용하지 않습니다. 3x 마을 사람들의 숫자는 다음과 같습니다.

10진법 3x 마을에서 쓰는 숫자 10진법 3x 마을에서 쓰는 숫자
1 1 6 8
2 2 7 10
3 4 8 11
4 5 9 14
5 7 10 16
정수 n이 매개변수로 주어질 때, n을 3x 마을에서 사용하는 숫자로 바꿔 return하도록 solution 함수를 완성해주세요.

 

🚨 제한 사항

  • 1 ≤ n ≤ 100

 

💻 입출력 예

n result
15 25
40 76

 

✨ 풀이 설명

마을 이름이 귀엽다
뭔가 수학적인 풀이 방법이 있을까 고민하다가 생각이 안 나, 그냥 반복문으로 풀었다.
문제에서 설명한 대로, 값에 3이 포함되어 있거나, 3의 배수일 경우 1을 더해주는 방식을 선택했다.
우선 다음 숫자로 가기 위해선 한 순서에서 무조건 1을 더해줘야 하기 때문에 그냥 while이 아닌, 우선 한 번 실행을 하는 do while을 사용해 봤다.
다른 풀이들을 보아도 수학적인 방법이 없는 것을 보면 반복문을 통해 해결하는 것 밖에는 없는 것 같다.

 

🕵️‍♂️ 코드

function solution(n) {
  let answer = 0;
  for (let i = 1; i <= n; i++) {
    do answer++;
    while (!(answer % 3) || (answer + '').includes(3))
  }
  return answer;
}

 


📝 [Lv0] 외계어 사전

👀 문제 설명

PROGRAMMERS-962 행성에 불시착한 우주비행사 머쓱이는 외계행성의 언어를 공부하려고 합니다. 알파벳이 담긴 배열 spell과 외계어 사전 dic이 매개변수로 주어집니다. spell에 담긴 알파벳을 한번씩만 모두 사용한 단어가 dic에 존재한다면 1, 존재하지 않는다면 2를 return하도록 solution 함수를 완성해주세요.

 

🚨 제한 사항

  • spell과 dic의 원소는 알파벳 소문자로만 이루어져있습니다.
  • 2 ≤ spell의 크기 ≤ 10
  • spell의 원소의 길이는 1입니다.
  • 1 ≤ dic의 크기 ≤ 10
  • 1 ≤ dic의 원소의 길이 ≤ 10
  • spell의 원소를 모두 사용해 단어를 만들어야 합니다.
  • spell의 원소를 모두 사용해 만들 수 있는 단어는 dic에 두 개 이상 존재하지 않습니다.
  • dic과 spell 모두 중복된 원소를 갖지 않습니다.

 

💻 입출력 예

spell dic result
["p", "o", "s"] ["sod", "eocd", "qixm", "adio", "soo"] 2
["z", "d", "x"] ["def", "dww", "dzx", "loveaw"] 1
["s", "o", "m", "d"] ["moos", "dzx", "smm", "sunmmo", "som"] 2

 

✨ 풀이 설명

우선 some()을 사용했다. some()은 배열에 대한 반복문을 돌며, 조건 중 하나라도 일치하는 것이 있다면 true를 반환한다.
만약 dic 배열 중, 하나라도 일치하는 것이 있다면 1을, 만약 없다면 2를 반환하도록 해주었다.
그리고 각 단어에 대해서는 every()를 사용했다. every()는 some()과는 반대로, 모든 조건이 만족해야 true를 반환한다.
나는 각 단어마다 spell의 글자가 존재하며 한 번씩만을 포함하는지 확인하였는데, 만약 한 글자라도 없거나 두 번 이상 포함한다면 false가 반환될 것이다.

 

🕵️‍♂️ 코드

function solution(spell, dic) {
  return +dic.some(word => spell.every(char =>
    word.includes(char) && word.indexOf(char) === word.lastIndexOf(char))
  ) || 2;
}

 


📝 [Lv0] 안전지대

👀 문제 설명

다음 그림과 같이 지뢰가 있는 지역과 지뢰에 인접한 위, 아래, 좌, 우 대각선 칸을 모두 위험지역으로 분류합니다.


지뢰는 2차원 배열 board에 1로 표시되어 있고 board에는 지뢰가 매설 된 지역 1과, 지뢰가 없는 지역 0만 존재합니다.
지뢰가 매설된 지역의 지도 board가 매개변수로 주어질 때, 안전한 지역의 칸 수를 return하도록 solution 함수를 완성해주세요.

 

🚨 제한 사항

  • board는 n * n 배열입니다.
  • 1 ≤ n ≤ 100
  • 지뢰는 1로 표시되어 있습니다.
  • board에는 지뢰가 있는 지역 1과 지뢰가 없는 지역 0만 존재합니다.

 

💻 입출력 예

board result
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0]] 16
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]] 13
[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]] 0

 

✨ 풀이 설명

board의 각 칸을 돌면서 1(지뢰)인 곳을 찾아 minesweeper()로 넘겨주었다.
minesweeper()에서는 지뢰의 팔방 중 board 영역이면서 안전지역이었던 곳일 경우, 위험지역(2로 설정) 표시를 해주었다.

마지막에 board에서 안전지역(0)인 곳의 개수를 모두 찾아 더해준 값을 반환해 주었다.

 

🕵️‍♂️ 코드

function solution(board) {
  const ROW = board.length, COL = board[0].length;
  const DIR = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]];

  const minesweeper = (x, y) => {
    for (const [dx, dy] of DIR) {
      if (x + dx >= 0 && x + dx < ROW && y + dy >= 0 && y + dy < COL && !board[x + dx][y + dy]) {
        board[x + dx][y + dy] = 2;
      }
    }
  }

  for (let i = 0; i < ROW; i++) {
    for (let j = 0; j < COL; j++) {
      if (board[i][j] === 1) minesweeper(i, j);
    }
  }

  return board.reduce((safe, line) => safe + line.filter(block => !block).length, 0);
}

 


📝 [Lv0] 컨트롤 제트

👀 문제 설명

숫자와 "Z"가 공백으로 구분되어 담긴 문자열이 주어집니다. 문자열에 있는 숫자를 차례대로 더하려고 합니다. 이 때 "Z"가 나오면 바로 전에 더했던 숫자를 뺀다는 뜻입니다. 숫자와 "Z"로 이루어진 문자열 s가 주어질 때, 머쓱이가 구한 값을 return 하도록 solution 함수를 완성해보세요.

 

🚨 제한 사항

  • 1 ≤ s의 길이 ≤ 200
  • -1,000 < s의 원소 중 숫자 < 1,000
  • s는 숫자, "Z", 공백으로 이루어져 있습니다.
  • s에 있는 숫자와 "Z"는 서로 공백으로 구분됩니다.
  • 연속된 공백은 주어지지 않습니다.
  • 0을 제외하고는 0으로 시작하는 숫자는 없습니다.
  • s는 "Z"로 시작하지 않습니다.
  • s의 시작과 끝에는 공백이 없습니다.
  • "Z"가 연속해서 나오는 경우는 없습니다.

 

💻 입출력 예

s result
"1 2 Z 3" 4
"10 20 30 40" 100
"10 Z 20 Z 1" 1
"10 Z 20 Z" 0
"-1 -2 -3 Z" -3

 

✨ 풀이 설명

문제를 읽자마자 스택...? 이라고 생각했다.
숫자는 더하면서 Z가 나올 때마다 "뒤에서부터 하나씩 뺀다"는 것이 꼭 스택을 떠올리게 했기 때문이다.

그래서 문자열을 우선 공백 기준으로 나눠준 다음, 나눈 문자를 +연산자를 사용해서 강제 형변환 했을 때, 정수인지 확인했다.
만약 정수일 경우에는 stack에 추가해 주고, 아닐 경우(Z일 경우)는 마지막에 더한 숫자를 빼주었다.
Number.isInteger()은 값이 정수인지 아닌지를 판별해 주는 함수이다.

stack에는 빼지 않은 숫자들이 남아있을 것이고, 이 값들을 모두 더해 반환해 주었다.

 

🕵️‍♂️ 코드

function solution(s) {
  const stack = [];
  s.split(' ').forEach(word => Number.isInteger(+word) ? stack.push(word) : stack.pop());
  return stack.reduce((sum, num) => sum + +num, 0);
}

 


📝 [Lv0] 배열 원소의 길이

👀 문제 설명

문자열 배열 strlist가 매개변수로 주어집니다. strlist 각 원소의 길이를 담은 배열을 retrun하도록 solution 함수를 완성해주세요.

 

🚨 제한 사항

  • 1 ≤ strlist 원소의 길이 ≤ 100
  • strlist는 알파벳 소문자, 대문자, 특수문자로 구성되어 있습니다.

 

💻 입출력 예

strlist result
["We", "are", "the", "world!"] [2, 3, 3, 6]
["I", "Love", "Programmers."] [1, 4, 12]

 

✨ 풀이 설명

map()을 사용할 줄 안다면 정말 간단하게 해결되는 문제였다. map()으로 각 단어들의 길이를 반환하여 새로운 배열을 만들면 정답을 도출해 낼 수 있다.

 

🕵️‍♂️ 코드

function solution(strlist) {
  return strlist.map(str => str.length);
}

 

728x90