Coding Problem

[프로그래머스] 당구 연습

Yepchani 2025. 1. 28. 14:00
반응형

문제

당구 연습

https://school.programmers.co.kr/learn/courses/30/lessons/169198

 

 

풀이

설명

각 회마다 머쓱이가 친 공이 굴러간 거리의 최솟값의 제곱을 구하는 문제입니다.

 

머쓱이가 친 공을 S, 쳐야할 공을 T, 공이 부딪힌 벽이나 꼭짓점을 A라고 할 때,

공이 굴러간 거리 = S와 A 사이의 거리 + T와 A 사이의 거리 입니다.

 

공이 굴러간 거리를 쉽게 계산하기 위해, T의 좌표를 S에 가까운 벽이나 꼭짓점에 대해서 대칭시킨 좌표를 구합니다.

 

벽과 꼭짓점에 따라서 부딪힌 후 공을 맞출 수 있는지 여부를 따로 체크해야 합니다.


  • 어떤 벽 W의 임의의 점 A에서 W에 수직인 직선을 하나 그었을 때 S, T,  A의 순서로 위치한 경우, S는 W에 부딪힌 후 T를 맞출 수 없습니다.
  • 꼭짓점
    어떤 꼭짓점 C를 지나는 직선 위에 S, T, C의 순서로 위치한 경우, S는 C에 부딪힌 후 T를 맞출 수 없습니다.

 

예시 코드

function solution(m, n, startX, startY, balls) {
  const results = [];

  balls.forEach((ball) => {
    const [targetX, targetY] = ball;
    const distances = [];

    // 벽
    // y = n
    if (startX !== targetX || startY > targetY)
      distances.push(getDistance(startX, startY, targetX, 2 * n - targetY));
    // y = 0
    if (startX !== targetX || startY < targetY)
      distances.push(getDistance(startX, startY, targetX, -targetY));
    // x = m
    if (startY !== targetY || startX > targetX)
      distances.push(getDistance(startX, startY, 2 * m - targetX, targetY));
    // x = 0
    if (startY !== targetY || startX < targetX)
      distances.push(getDistance(startX, startY, -targetX, targetY));

    // 꼭짓점
    const dx = targetX - startX;
    const dy = targetY - startY;
    // (0, 0)
    if (dx * startY === dy * startX && startX < targetX && startY < targetY)
      distances.push(getDistance(startX, startY, -targetX, -targetY));
    // (0, n)
    if (
      dx * (startY - n) === dy * startX &&
      startX < targetX &&
      startY > targetY
    )
      distances.push(getDistance(startX, startY, -targetX, 2 * n - targetY));
    // (m, 0)
    if (
      dx * startY === dy * (startX - m) &&
      startX > targetX &&
      startY < targetY
    )
      distances.push(getDistance(startX, startY, 2 * m - targetX, -targetY));
    // (m, n)
    if (
      dx * (startY - n) === dy * (startX - m) &&
      startX > targetX &&
      startY > targetY
    )
      distances.push(
        getDistance(startX, startY, 2 * m - targetX, 2 * n - targetY)
      );

    results.push(Math.min(...distances));
  });

  return results;
}

function getDistance(x1, y1, x2, y2) {
  return (x2 - x1) ** 2 + (y2 - y1) ** 2;
}