[프로그래머스 1레벨] 키패드 누르기

이민선(Jasmine)·2023년 1월 26일
1
post-thumbnail

절대 안풀릴 것 같던 문제를 드디어 풀었다 ㅠㅠ 감격 ㅠㅠ
어제 문자열 나누기 문제를 재귀함수로 풀어냈던 누군가의 코드가 기억에 남은 덕분에
오늘 키패드 누르기 문제도 재귀함수로 접근하면 어떨까 생각을 해봤고, 결과는 통과!!

나의 코드

function solution(numbers, hand, fingerL = "*", fingerR = "#", ans = "") {
  const [h, L, R] = [hand[0].toUpperCase(), [1, 4, 7], [3, 6, 9]];
  let cur = numbers[0];

  if (L.includes(cur)) {
    ans += "L";
    fingerL = cur;
  } else if (R.includes(cur)) {
    ans += "R";
    fingerR = cur;
  } else {
    ans += distance([fingerL, fingerR], cur, h);
    distance([fingerL, fingerR], cur, h) === "L"
      ? (fingerL = cur)
      : (fingerR = cur);
  }

  numbers.splice(0, 1);
  if (numbers.length === 0) return ans;
  return solution(numbers, hand, fingerL, fingerR, ans);
}

function distance([L, R], cur, h) {
  const keypads = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    ["*", 0, "#"],
  ];
  let [[iL, jL], [iR, jR], [iCur, jCur]] = [[], [], []];
  for (let v of keypads)
    if (v.includes(L)) [iL, jL] = [keypads.indexOf(v), v.indexOf(L)];
  for (let v of keypads)
    if (v.includes(R)) [iR, jR] = [keypads.indexOf(v), v.indexOf(R)];
  for (let v of keypads)
    if (v.includes(cur)) [iCur, jCur] = [keypads.indexOf(v), v.indexOf(cur)];
  let distanceFromL = Math.abs(iCur - iL) + Math.abs(jCur - jL);
  let distanceFromR = Math.abs(iCur - iR) + Math.abs(jCur - jR);
  return distanceFromL < distanceFromR
    ? "L"
    : distanceFromL === distanceFromR
    ? h
    : "R";
}

fingerL과 fingerR이라는 매개변수를 추가했다.
fingerL과 fingerR은 각각 현재 손가락의 위치를 나타낸다.
맨 처음에는 문제에 제시된 대로 default 값으로 각각 *과 #을 준다.

그리고 if문을 사용하여 현재 눌러야할 버튼(cur)이 L 배열[1,4,7]에 포함되어 있다면 ans에 L을 더해주고 fingerL을 현재 누른 버튼 cur로 바꾸어준다. (fingerR)은 불변.
마찬가지로 현재 눌러야할 버튼(cur)이 R 배열[3,6,9]에 포함되어 있다면 ans에 R을 더해주고 fingerR을 현재 누른 버튼 cur로 바꾸어준다. (fingerL)은 불변.
현재 눌러야할 버튼(cur)이 1,4,7도 아니고 3,6,9도 아니라면?
distance함수를 호출하여 현재 눌러야할 버튼(cur)과 fingerL, fingerR과의 거리를 각각 구한다.
당연히 더 거리가 더 짧은 쪽을 택한다.
cur과 fingerL과의 거리가 더 짧다면 L을 반환, cur과 fingerR과의 거리가 더 짧다면 R을 반환.
거리가 같다면? h(왼손잡이인 경우 L, 오른손잡이인 경우 R)을 반환하여 ans에 더해준다.

그럼 거리는 어떻게 구했느냐?
만약 cur과 fingerL 간의 거리를 구한다면, cur과 fingerL 간에 keypads 상에서 행의 차이와 열의 차이를 더하였다.

if문이 종료되면 재귀함수를 사용하기 위해 numbers는 앞 글자를 똑 떼고 재선언(splice 활용)
solution의 매개변수로 앞 글자를 똑 뗸 numbers, hand, (왼손으로 cur을 눌렀다면 재선언된) L, (오른손으로 cur을 눌렀다면 재선언된) R, ans를 넘겨준다.

처음으로 재귀함수를 이용해서 문제를 풀어보았다!
저렇게 어려워보이는 개념으로 코드를 작성이나 해볼 수 있을까하고 막연하게 생각해왔는데 실제로 사용해보니 뿌듯하군!!

1레벨도 3문제 남았다 후후 이번 달 안에 끝내자 화이팅 쟤스민~~~
이제 리액트 하러!!숑숑!!!

profile
기록에 진심인 개발자 🌿

0개의 댓글