[알고리즘] 프로그래머스 - 키패드 누르기

선영·2022년 5월 17일
0

알고리즘

목록 보기
2/10
post-thumbnail

문제 링크
풀이참고 링크
나의 문제풀이

⭐️ 문제해결 포인트


키패드 사이의 거리 구하기

손인덱스, 누를숫자인덱스를 인자로 받는 getDistance함수를 아래와 같이 구현하여 왼손 거리, 오른손 거리를 각각 구한다.
ToDo 사실 아래 거리를 구하는 식을 완벽히 이해 못했다. 좀 더 공부해보자.

function getDistance(handIndex, targetNumberIndex) {
    return Math.ceil(
      Math.sqrt(
        Math.pow(handIndex[0] - targetNumberIndex[0], 2) +
        Math.pow(handIndex[1] - targetNumberIndex[1], 2)
      ));
  }

학습한 부분


할당 연산자

표현식 및 연산자 MDN

let answer = "" 에서 let answer = "LRLL..." 와 같이 문자를 누적시켜 새로운 문자열을 만들려 했다.
처음엔 concat() 메서드를 사용하려고 했는데, answer += "L" 와 같이 할당 연산자를 사용하는게 성능향상에 더 좋다.

arr.indexOf()

배열과 메서드

1/ true일 경우 => [1, 2, 3].indexOf(1) 을 하게 되면 0을 반환한다.
2/ false일 경우 => [1, 2, 3].indexOf(4) 을 하게 되면 -1를 반환한다.


코드


function solution(numbers, hand) {
  let answer = "";

  let leftHandIndex = [3, 0];
  let rightHandIndex = [3, 2];

  const leftNumbers = [1, 4, 7];
  const centerNumbers = [2, 5, 8, 0];
  const rightNumbers = [3, 6, 9];

  function getDistance(hand, target) {
    return Math.ceil(
      Math.sqrt(
        Math.pow(hand[0] - target[0], 2) +
        Math.pow(hand[1] - target[1], 2)
      ));
  }

  numbers.map(number => {
    if (leftNumbers.includes(number)) {
      answer += "L";
      leftHandIndex = [
        leftNumbers.indexOf(number), 0
      ];
    } else if (centerNumbers.includes(number)) {
      const targetIndex = [
        centerNumbers.indexOf(number), 1
      ];

      const leftDis = getDistance(
        leftHandIndex, targetIndex
      );
      const rightDis = getDistance(
        rightHandIndex, targetIndex
      );

      if (leftDis > rightDis) { // 오른손이 더 가깝
        answer += "R";
        rightHandIndex = targetIndex;
      } else if (rightDis > leftDis) { // 왼손이 더 가깝
        answer += "L";
        leftHandIndex = targetIndex;
      } else if (rightDis == leftDis) { // 같은 경우
        if (hand == "right") {
          answer += "R";
          rightHandIndex = targetIndex;
        } else if (hand == "left") {
          answer += "L";
          leftHandIndex = targetIndex;
        }
      }

    } else if (rightNumbers.includes(number)) {
      answer += "R";
      rightHandIndex = [
        rightNumbers.indexOf(number), 0
      ];
    }
  });

  return answer;
}

// => Target result "LRLLLRLLRRL"

console.log(solution(
  [1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5],
  "right",
));

자기 선언


처음에 문제를 풀땐 keyPad를 굳이 2차원 배열로 만들어서 2중 for문을 돌렸더니 side effect가 있었는지 테스트케이스를 모두 통과하지 않았었다.
되도록 immutable 하도록 배열을 조작할때 map메서드를 쓰도록하자.


✅ 다시 풀기


1.

다시 풀 땐 if문만 사용했더니 테스트케이스 실패가 잔뜩떴다.
아래 블로그에서 설명하는 것 처럼 if가 참이 되면 else-if는 실행되지 않고 넘어가게 된다.
반면 if-if문만 사용하게 되면 if가 참이던 말던 모든 if문들은 실행된다. 때문에 if-else if-else를 적절하게 사용하는 것이 중요하다.
https://transferhwang.tistory.com/81

2.

배열 요소에 타이포가 있어서 30분정도 삽질했다. 테스트 케이스가 통과안하면 타이포가 없는지 먼저 확인하자.

profile
Superduper-India

0개의 댓글