티스토리 뷰

반응형

 

프로그래머스 - 키패드 누르기

 

문제의 의도를 처음부터 잘 못 파악하며 풀었다. 왼손과 오른손 값이 같을 때 더 가까운 손으로 누르라고 한 부분에서 키패드 위치 값이 아닌 단순히 숫자의 차로 오해했다. 

 

아무튼 그냥 각 숫자에 해당하는 손을 answer에 push하고 center부분에서 조건을 따지려고 했는데 그때서야 잘못 파악한 걸 알아차렸고,,

접근을 어떻게해야할지 모르겠어서 다른 분의 풀이를 참고했다. 

 

이 문제는 right, left의 값을 계속해서 상황에 맞게 업데이트해주고, 두 지점 간 거리를 절댓값으로 구하는 것 이 두 가지가 핵심이 되겠다. 

 

예전에 이런식으로 위치를 좌표값처럼 생각해서 접근한 적이 있었는데 이런 유형의 문제도 잘 기억해둬야겠다는 생각이 들었다.

 

 


 

 

내가 풀었던 부분인데, 나는 key와 value를 이용해 value가 numbers에 있다면 그에 해당하는 key값을 push 해주는 식이다.

결론은 아래처럼 리턴이 되고 나는 여기서 center값만 비교하려 한건데 여기서부터 전에 값을 참조하는 것에서 방향성을 잃었다...ㅎ

[ 'L', 'R', 'L', 'center', 'center', 'center', 'L', 'L', 'center', 'R', 'center' ]

 

function solution(numbers, hand) {
  let answer = [];
  
  // left 1,4,7
  // right 3,6,9
  // 2,5,8,0 더 가까운 손으로, 거리 같다면 본인손잡이로

  const keyPad = {
    L: [1, 4, 7],
    R: [3, 6, 9],
    center: [2, 5, 8, 0],
  };

  let handPosition = [];

  for (let i = 0; i < numbers.length; i++) {
    Object.keys(keyPad).find((key) => {
      if (keyPad[key].includes(numbers[i])) {
        if (key === "center") {
        }
        handPosition.push(key);
      }
    });
  }
  return answer;
}
console.log(solution([1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5], "right"));

 

 


 

풀이과정

 

1. 문제에서 명시된 것을 처음부터 표현해주었다.

맨 처음 왼손 엄지손가락은 *키패드에 오른손 엄지손가락은 #키패드 위치에서 시작
  let leftHandPosition = "*";
  let rightHandPosition = "#";

 

 

 

2. 각 조건에 맞는 숫자가 있으면 answer에 push 한다. 

엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
  numbers.forEach((num) => {
    if (num === 1 || num === 4 || num === 7) {
      answer.push("L");
      leftHandPosition = num;
      return;
    }

    if (num === 3 || num === 6 || num === 9) {
      answer.push("R");
      rightHandPosition = num;
      return;
    }
    
  ...
  
  });

 

 

 

3. 해당하는 값이 아닌 (2,5,8,0) 중 하나를 눌렀을 경우 

가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.

 

위 조건을 충족하기 위해 이전에 눌렀던 leftHandPosition, rightHandPosition 값과 현재 누른 값(target) 사이의 거리를 구해주는 getDistance함수를 생성한다. 

  numbers.forEach((num) => {
	...
    const leftHandDistance = getDistance(leftHandPosition, num);
    const rightHandDistance = getDistance(rightHandPosition, num);
    
  	...
  });

 

getDistance 함수 

keyPad를 딕셔너리 형태로 만들고, Math.abs() 메서드를 활용해 두 숫자키패드간 거리를 구한다. 

const getDistance = (locatedNumber, target) => {
  const keyPad = {
    1: [0, 0],
    2: [0, 1],
    3: [0, 2],
    4: [1, 0],
    5: [1, 1],
    6: [1, 2],
    7: [2, 0],
    8: [2, 1],
    9: [2, 2],
    "*": [3, 0],
    0: [3, 1],
    "#": [3, 2],
  };

  const nowPosition = keyPad[locatedNumber];
  const targetPosition = keyPad[target];

  return (
    Math.abs(targetPosition[0] - nowPosition[0]) +
    Math.abs(targetPosition[1] - nowPosition[1])
  );
};

 

 

 

4. 구한 거리 값을 비교해 오른손 or 왼손  리턴

가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다. 4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.

 

위 조건에 해당하는 코드를 작성한다. getDustabce 함수만 잘 구했다면 이 조건은 어렵지 않게 쓸 수 있다.

  numbers.forEach((num) => {
	
    ...
    
 
    const leftHandDistance = getDistance(leftHandPosition, num);
    const rightHandDistance = getDistance(rightHandPosition, num);
    
  	 if (leftHandDistance === rightHandDistance) {
      if (hand === "right") {
        answer.push("R");
        rightHandPosition = num;
        return;
      } else {
        answer.push("L");
        leftHandPosition = num;
        return;
      }
    }

    if (leftHandDistance > rightHandDistance) {
      answer.push("R");
      rightHandPosition = num;
    } else {
      answer.push("L");
      leftHandPosition = num;
    }
 });

 

 

 


 

전체 답안

 

function solution(numbers, hand) {
  let answer = [];
  let leftHandPosition = "*";
  let rightHandPosition = "#";

  numbers.forEach((num) => {
    if (num === 1 || num === 4 || num === 7) {
      answer.push("L");
      leftHandPosition = num;
      return;
    }

    if (num === 3 || num === 6 || num === 9) {
      answer.push("R");
      rightHandPosition = num;
      return;
    }

    const leftHandDistance = getDistance(leftHandPosition, num);
    const rightHandDistance = getDistance(rightHandPosition, num);

    if (leftHandDistance === rightHandDistance) {
      if (hand === "right") {
        answer.push("R");
        rightHandPosition = num;
        return;
      } else {
        answer.push("L");
        leftHandPosition = num;
        return;
      }
    }

    if (leftHandDistance > rightHandDistance) {
      answer.push("R");
      rightHandPosition = num;
    } else {
      answer.push("L");
      leftHandPosition = num;
    }
  });

  return answer.join("");
}

const getDistance = (locatedNumber, target) => {
  const keyPad = {
    1: [0, 0],
    2: [0, 1],
    3: [0, 2],
    4: [1, 0],
    5: [1, 1],
    6: [1, 2],
    7: [2, 0],
    8: [2, 1],
    9: [2, 2],
    "*": [3, 0],
    0: [3, 1],
    "#": [3, 2],
  };

  const nowPosition = keyPad[locatedNumber];
  const targetPosition = keyPad[target];

  return (
    Math.abs(targetPosition[0] - nowPosition[0]) +
    Math.abs(targetPosition[1] - nowPosition[1])
  );
};
반응형