본문 바로가기
코테연습

45. 키패드 누르기

by hxunz 2022. 5. 17.

https://programmers.co.kr/learn/courses/30/lessons/67256

 

코딩테스트 연습 - 키패드 누르기

[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] "right" "LRLLLRLLRRL" [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] "left" "LRLLRRLLLRR" [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] "right" "LLRLLRLLRL"

programmers.co.kr

 

아직은 나에게 항상 어려운,, 카카오 코테,,

 

1. 이해
상하좌우로 1씩 이동
1, 4, 7 -> L
3, 6, 9 -> R
2, 5, 8, 0 -> 가까운 손 (왼손잡이->L / 오른손잡이->R)

 

2. 계획
  • 2,5,8,0이 없다고 가정하고 1,3,5와 3,6,9에 대한 처리
  • 키패드를 좌표 처리 해줌
  • 손가락의 처음 위치는 왼손은 * 오른손은 #
  • 2,5,8,0이 있다면 (절대값처리 해줘야함)
    1. (현재 숫자의 x좌표 - 왼손이 위치한 키패드의 x좌표) + (현재 숫자의 y좌표 - 왼손이 위치한 키패드의 y좌표)
    2. (현재 숫자의 x좌표 - 오른손이 위치한 키패드의 x좌표) + (현재 숫자의 y좌표 - 오른손이 위치한 키패드의 y좌표)
  • 이 두 값을 비교
  • 더 적은 수가 거리가 가깝다는거 -> 더 적은 수가 나온 손 리턴
  • 만약에 값이 같다면 hand에서 해당하는 손 리턴
  • 마지막에 배열을 스트링으로 변환
const LeftNumbers = [1, 4, 7];
const RightNumbers = [3, 6, 9];
const Keypad = {
  1: [1, 1], 2: [1, 2], 3: [1, 3],
  4: [2, 1], 5: [2, 2], 6: [2, 3],
  7: [3, 1], 8: [3, 2], 9: [3, 3],
  '*': [4, 1], 0: [4, 2], '#': [4, 3],
};

function calculateDistance(currentLocation, compareLocation) {
  return Math.abs(currentLocation[0] - compareLocation[0]) + Math.abs(currentLocation[1] - compareLocation[1]);
}

function solution(numbers, hand) {
  let leftHand = '*';
  let rightHand = '#';

  return numbers.map(number => {
    if (LeftNumbers.includes(number)) {
      leftHand = number;
      return 'L';
    }
    if (RightNumbers.includes(number)){
      rightHand = number;
      return 'R';
    }
    const leftDistance = calculateDistance(Keypad[number], Keypad[leftHand]);
    const rightDistance = calculateDistance(Keypad[number], Keypad[rightHand]);

    if (leftDistance === rightDistance) {
      if (hand === 'right') {
        rightHand = number;
        return 'R';
      }
      leftHand = number;
      return 'L';
    }
    if (leftDistance > rightDistance) {
      rightHand = number;
      return 'R';
    }
    leftHand = number;
    return 'L';
  }).join('');
}

우선, 상수값들은 function 밖으로 빼줬다. 

그리고 상수값을 담은 이름은 첫글자를 대문자로 해주는게 좋다.

const LeftNumbers = [1, 4, 7];
const RightNumbers = [3, 6, 9];
const Keypad = {
1: [1, 1], 2: [1, 2], 3: [1, 3],
4: [2, 1], 5: [2, 2], 6: [2, 3],
7: [3, 1], 8: [3, 2], 9: [3, 3],
'*': [4, 1], 0: [4, 2], '#': [4, 3],
};
 

그리고 거리 구하는 함수도 따로 작성해서 solution함수 밖으로 빼줬다.

function calculateDistance(currentLocation, compareLocation) {
return Math.abs(currentLocation[0] - compareLocation[0]) + Math.abs(currentLocation[1] - compareLocation[1]);
}

번호를 좌표로 나타냈기 때문에 좌표에서 거리 구하는 방법을 사용했다. 

절댓값으로 바꿔줘야하니까 Math.abs()를 사용했다.

* 왼손에서 현재 숫자 사이의 거리

 -> (현재 숫자의 x좌표 - 왼손이 위치한 키패드의 x좌표) + (현재 숫자의 y좌표 - 왼손이 위치한 키패드의 y좌표)

* 오른손에서 현재 숫자 사이의 거리
 -> (현재 숫자의 x좌표 - 오른손이 위치한 키패드의 x좌표) + (현재 숫자의 y좌표 - 오른손이 위치한 키패드의 y좌표)

 

일단, 밖에서 이렇게 처리해두고~

 

손가락의 처음 위치는 왼손은 * 오른손은 #

let leftHand = '*';
let rightHand = '#';

우선, for 반복문은 지양해야하기 때문에 map을 쓴다.

return numbers.map(number => {}
이 중괄호에 아래의 내용이 들어간다.
 

숫자가 1,4,7 일때 -> 무조건 왼손

if (LeftNumbers.includes(number)) {
leftHand = number;
return 'L';
}

숫자가 3,6,9일때 -> 무조건 오른손

if (RightNumbers.includes(number)){
rightHand = number;
return 'R';
}

 

둘 다 아닌경우 2, 5, 8, 0 중 하나인 경우

위에서 만들어놓은 거리 계산하는 함수를 사용한다.

const leftDistance = calculateDistance(Keypad[number], Keypad[leftHand]);
const rightDistance = calculateDistance(Keypad[number], Keypad[rightHand]);

 

계산했는데 거리가 같은 경우 hand에 따라서 달라지니까 

if (leftDistance === rightDistance) {
if (hand === 'right') {
rightHand = number;
return 'R';
}
leftHand = number;
return 'L';
}

 

왼손거리가 더 큰 경우 -> 왼손 거리가 더 멀다는 의미 -> R 리턴

오른손거리가 더 큰 경우 -> 오른손 거리가 더 멀다는 의미 -> L 리턴

if (leftDistance > rightDistance) {
rightHand = number;
return 'R';
}
leftHand = number;
return 'L';

 

map 함수를 썼으니까 이 모든게 배열로 담긴다. 

그러니까 마지막에 스트링으로 바꿔줘야한다.

.join('');

끝~~

 

 

 

 

테스트 코드도 짜봤다 ..!
코테 풀때라도 테스트코드 작성하는것을 익혀야겠다.

test('키패드 누르기', () => {
  const numbers = [1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5];
  const hand = "right";
  expect(solution(numbers, hand)).toBe("LRLLLRLLRRL");
});

'코테연습' 카테고리의 다른 글

47-1. 3진법 뒤집기  (0) 2022.05.17
46. 음양더하기  (0) 2022.05.17
44. 없는 숫자 더하기  (0) 2022.05.13
43. 크레인 인형 뽑기 게임  (0) 2022.05.13
42. 숫자 문자열과 영단어  (0) 2022.05.12

댓글