본문 바로가기
codingtest

[programmers] 겹치는 선분의 길이, 캐릭터의 좌표, 문자열 정렬하기 (1), 평행, 나머지 구하기

by 안자두 2023. 3. 24.

📝 [Lv0] 겹치는 선분의 길이

👀 문제 설명

선분 3개가 평행하게 놓여 있습니다. 세 선분의 시작과 끝 좌표가 [[start, end], [start, end], [start, end]] 형태로 들어있는 2차원 배열 lines가 매개변수로 주어질 때, 두 개 이상의 선분이 겹치는 부분의 길이를 return 하도록 solution 함수를 완성해보세요.

lines가 [[0, 2], [-3, -1], [-2, 1]]일 때 그림으로 나타내면 다음과 같습니다.

선분이 두 개 이상 겹친 곳은 [-2, -1], [0, 1]로 길이 2만큼 겹쳐있습니다.

 

🚨 제한 사항

  • lines의 길이 = 3
  • lines의 원소의 길이 = 2
  • 모든 선분은 길이가 1 이상입니다.
  • lines의 원소는 [a, b] 형태이며, a, b는 각각 선분의 양 끝점 입니다.
    • -100 ≤ a < b ≤ 100

 

💻 입출력 예

lines result
[[0, 1], [2, 5], [3, 9]] 2
[[-1, 1], [1, 3], [3, 9]] 0
[[0, 5], [3, 9], [1, 10]] 8

 

✨ 풀이 설명

선분의 길이가 최대 -100부터 100까지이고, 총 3개뿐이어서 직관적으로 배열에 저장하는 방식으로 풀이하였다.
길이가 더 길어지거나 개수가 많아지게 되면 시간 효율이 나빠지게 되지만, 이렇게 적은 양에 대해서는 겹치는 부분을 직접 비교하며 구하는 것보다 이 방법이 더 좋을 것 같다는 생각이 들었다.

우선 각 길이를 저장해 줄 최대 길이만큼의 배열이 필요하다. -100부터 100까지를 0부터 200까지라고 생각하여 최대 200개의 배열을 생성해 주었다.
배열의 각각의 칸에는 선분의 모든 좌표를 표시해 줄 것이다.
만약, 선분의 길이가 -3부터 10이라면, 새로운 배열 line에는 반복문을 돌며 line의 97부터 110 전까지 선분이 존재한다는 뜻으로 1씩 더해주었다.

모든 선분에 대해 이 과정을 진행하면 line에는 최대 세 선분이 모두 겹칠 경우인 3이 저장될 수 있다.
마지막으로 line을 순회하며, 선분이 두 번 이상 겹쳤을 경우인 2 이상이 저장되어 있는 좌표를 모두 더해주면, 겹치는 선분의 길이를 구할 수 있다.

 

🕵️‍♂️ 코드

function solution(lines) {
  const line = new Array(200).fill(0);
  lines.forEach(([start, end]) => {
    for (let i = start; i < end; i++) line[i + 100]++;
  });
  return line.reduce((sum, item) => item < 2 ? sum : sum + 1, 0);
}

 


📝 [Lv0] 캐릭터의 좌표

👀 문제 설명

머쓱이는 RPG게임을 하고 있습니다. 게임에는 up, down, left, right 방향키가 있으며 각 키를 누르면 위, 아래, 왼쪽, 오른쪽으로 한 칸씩 이동합니다. 예를 들어 [0,0]에서 up을 누른다면 캐릭터의 좌표는 [0, 1], down을 누른다면 [0, -1], left를 누른다면 [-1, 0], right를 누른다면 [1, 0]입니다. 머쓱이가 입력한 방향키의 배열 keyinput와 맵의 크기 board이 매개변수로 주어집니다. 캐릭터는 항상 [0,0]에서 시작할 때 키 입력이 모두 끝난 뒤에 캐릭터의 좌표 [x, y]를 return하도록 solution 함수를 완성해주세요.

  • [0, 0]은 board의 정 중앙에 위치합니다. 예를 들어 board의 가로 크기가 9라면 캐릭터는 왼쪽으로 최대 [-4, 0]까지 오른쪽으로 최대 [4, 0]까지 이동할 수 있습니다.

 

🚨 제한 사항

  • board은 [가로 크기, 세로 크기] 형태로 주어집니다.
  • board의 가로 크기와 세로 크기는 홀수입니다.
  • board의 크기를 벗어난 방향키 입력은 무시합니다.
  • 0 ≤ keyinput의 길이 ≤ 50
  • 1 ≤ board[0] ≤ 99
  • 1 ≤ board[1] ≤ 99
  • keyinput은 항상 up, down, left, right만 주어집니다.

 

💻 입출력 예

keyinput board result
["left", "right", "up", "right", "right"] [11, 11] [2, 1]
["down", "down", "down", "down", "down"] [7, 9] [0, -4]

 

✨ 풀이 설명

각 방향에 대한 좌표를 객체로 선언해 주었다. 가로 세로의 최대 길이 또한 width와 height로 초기화해주었다.
그다음, 현재 위치 x, y를 0, 0으로 초기화해준 후, 각 key에 맞춰 방향을 움직여주었다.
만약, 최대 길이보다 커질 경우에는 해당 값을 최대 길이로 재할당했다.

 

🕵️‍♂️ 코드

function solution(keyinput, board) {
  const DIR = { left: [-1, 0], right: [1, 0], up: [0, 1], down: [0, -1] }
  const [width, height] = board.map(e => (e - 1) / 2);

  let [x, y] = [0, 0];
  keyinput.forEach(key => {
    const [dx, dy] = DIR[key];
    x = width * -1 > x + dx ? width * -1 : width < x + dx ? width : x + dx;
    y = height * -1 > y + dy ? height * -1 : height < y + dy ? height : y + dy;
  });

  return [x, y];
}

 


📝 [Lv0] 문자열 정렬하기 (1)

👀 문제 설명

문자열 my_string이 매개변수로 주어질 때, my_string 안에 있는 숫자만 골라 오름차순 정렬한 리스트를 return 하도록 solution 함수를 작성해보세요.

 

🚨 제한 사항

  • 1 ≤ my_string의 길이 ≤ 100
  • my_string에는 숫자가 한 개 이상 포함되어 있습니다.
  • my_string은 영어 소문자 또는 0부터 9까지의 숫자로 이루어져 있습니다.

 

💻 입출력 예

my_string result
"hi12392" [1, 2, 2, 3, 9]
"p2o4i8gj2" [2, 2, 4, 8]
"abcde0" [0]

 

✨ 풀이 설명

map()이나 filter()를 사용하면 숫자 또한 문자열로 되어있어서 반환할 때 형식이 숫자 형식이 되려면 두 번을 사용해 주어야 한다. (map()은 원본과 같은 길이의 배열을, filter()는 조건에 해당하는 원본 값을 반환하기 때문)
그래서 reduce()를 사용해 filter()처럼 숫자만을 뽑으면서도 반환할 때는 문자에서 숫자 타입으로 변환하여 반환해 주었다.
그다음 뽑아낸 숫자 배열을 정렬해 주면 끝!

 

🕵️‍♂️ 코드

function solution(my_string) {
  return [...my_string].reduce((list, char) => {
    isNaN(+char) || list.push(+char);
    return list;
  }, []).sort((a, b) => a - b);
}

 


📝 [Lv0] 평행

👀 문제 설명

점 네 개의 좌표를 담은 이차원 배열  dots가 다음과 같이 매개변수로 주어집니다.

  • [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]

주어진 네 개의 점을 두 개씩 이었을 때, 두 직선이 평행이 되는 경우가 있으면 1을 없으면 0을 return 하도록 solution 함수를 완성해보세요.

 

🚨 제한 사항

  • dots의 길이 = 4
  • dots의 원소는 [x, y] 형태이며 x, y는 정수입니다.
    • 0 ≤ x, y ≤ 100
  • 서로 다른 두개 이상의 점이 겹치는 경우는 없습니다.
  • 두 직선이 겹치는 경우(일치하는 경우)에도 1을 return 해주세요.
  • 임의의 두 점을 이은 직선이 x축 또는 y축과 평행한 경우는 주어지지 않습니다.

 

💻 입출력 예

dots result
[[1, 4], [9, 2], [3, 8], [11, 6]] 1
[[3, 5], [4, 1], [2, 4], [5, 10]] 0

 

✨ 풀이 설명

두 직선이 평행하는 경우는, 두 직선의 기울기가 일치할 때뿐이다. 
각 점들을 이어 기울기가 일치할 때가 있는지 확인해 주면 된다.

두 점을 넘겨 기울기를 구해주는 gradient() 함수와 네 점을 넣으면 두 점씩 기울기를 비교해 주는 compare() 함수를 구현해 주었다.

점이 4개이기 때문에 총 3번을 비교해 주면 된다. 점들을 비교할 순서대로 compare() 함수에 넣어주고 논리 연산자(||)를 통해 값을 비교해 주었다. 만약 세 번의 비교 중 기울기가 같은 값이 나온다면 중간에 1이 반환되어 멈출 것이고, 마지막까지 기울기가 같은 값이 나오지 않는다면 마지막 비교 때 반환된 0이 solution()의 값으로 반환될 것이다.

 

🕵️‍♂️ 코드

const gradient = ([x1, y1], [x2, y2]) => (y2 - y1) / (x2 - x1);
const compare = (a, b, c, d) => +(gradient(a, b) === gradient(c, d));

function solution(dots) {
  const [dot1, dot2, dot3, dot4] = dots;
  return compare(dot1, dot2, dot3, dot4) || compare(dot1, dot3, dot2, dot4) || compare(dot1, dot4, dot2, dot3);
}

 


📝 [Lv0] 나머지 구하기

👀 문제 설명

정수 num1, num2가 매개변수로 주어질 때, num1 num2로 나눈 나머지를 return 하도록 solution 함수를 완성해주세요.

 

🚨 제한 사항

  • 0 < num1 ≤ 100
  • 0 < num2 ≤ 100

 

💻 입출력 예

num1 num2 result
3 2 1
10 5 0

 

✨ 풀이 설명

나머지 연산자로 num1을 num2로 나눈 나머지를 구해 반환해 주었다.

 

🕵️‍♂️ 코드

function solution(num1, num2) {
  return num1 % num2;
}

 

728x90