230421_Algorithm

majungha·2023년 4월 21일
1

알고리즘

목록 보기
31/71

오늘의 알고리즘 👍

📝 1. 키패드 누르기


  • 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
  • 맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.
    1. 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
    1. 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
    1. 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
    1. 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
    • 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.
    1. 순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.

▷ 입출력 예

solution([1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5], 'right') // 'LRLLLRLLRRL'
solution([7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2], 'left') // "LRLLRRLLLRR"
solution([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], 'right') // "LLRLLRLLRL"

▷ 내 풀이

const leftHand = [1, 4, 7];
const rightHand = [3, 6, 9];

function solution(numbers, hand) {
  let answer = '';
  let leftLocation = '';
  let rightLocation = '';
  for (let i = 0; i < numbers.length; i++) {
    for (let j = 0; j < leftHand.length; j++) {
      if (numbers[i] === leftHand[j]) {
        answer += 'L';
        leftLocation = leftHand[j];
        console.log(leftLocation, '');
      } else if (numbers[i] === rightHand[j]) {
        answer += 'R';
        rightLocation = leftHand[j];
        console.log(rightLocation);
      } else {
        // if(numbers[i]  - rightLocation > numbers[i] - leftLocation){
        //   answer += 'L'
        // } else {
        //   answer += 'R'
        // }
      }
    }
  }

  return answer;
}

▷ 해결 못함 ❌

  • 2,5,8,0 에 접근하려면 위치값을 인덱스로 사용해서 풀면 될거같은데 시간이 부족해서 풀지 못하였다.
  • 내 풀이처럼 접근하면 왼손이 1, 오른손이 3일때 numbers[i]가 5이면 4, 2가 나오기 때문에 R로 픽스가 돼서 풀이가 불가능하다.

▷ 수업 풀이

const leftNumbers = [1, 4, 7]; // 왼손으로 눌러야 할 키패드들
const rightNumbers = [3, 6, 9]; // 오른손으로 눌러야 할 키패드들

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

  // 현재 손가락의 위치 (왼손. 오른손) = 어떤 키패드에 위치하고 있는지
  const current = {
    left: 10, // *에 해당하는 위치값
    right: 12, // #에 해당하는 위치값
  };

  for (let i = 0; i < numbers.length; i++) {
    if (leftNumbers.includes(numbers[i])) {
      // 누를 번호가 왼쪽 키패드에 해당하는 경우 = 왼손을 이용해 누른다.
      answer += 'L';
      current.left = numbers[i]; // 왼손의 위치 재할당
    } else if (rightNumbers.includes(numbers[i])) {
      // 누를 번호가 오른쪽 키패드에 해당하는 경우 = 오른손을 이용해 누른다.
      answer += 'R';
      current.right = numbers[i]; // 오른손의 위치 재할당
    } else {
      // 누를 번호가 가운데 키패드에 해당하는 경우 = 가까운 손을 이용해 누른다.
      const locationObj = { ...current }; // 양쪽의 손가락의 위치를 계산

      for (let hand in locationObj) {
        // 0번 키패드의 경우 0번 키패드에 해당하는 위치값(11)로 변경
        numbers[i] = numbers[i] === 0 ? 11 : numbers[i];

        // 가운데 키패드로부터 양쪽의 손이 몇칸 떨어져 있는지 계산
        let location = Math.abs(numbers[i] - locationObj[hand]);

        // 왼쪽이나 오른쪽으로 3칸 이상 이동했을 경우
        if (location >= 3) {
          location = Math.floor(location / 3) + (location % 3);
        }
        locationObj[hand] = location;
      }

      // 가운데 키패드의 번호로부터 양쪽의 손의 위치가 서로 동일하다면
      // 주로 사용하는 손(hand)을 이용해서 눌러준다
  if (locationObj.left === locationObj.right) {
    answer += hand === 'left' ? 'L' : 'R';
    current[hand] = numbers[i];
  } else {
    // 두 손의 위치가 서로 동일하지 않을 경우
    // 더 가까운 손을 이용해서 누른다.
    if (locationObj.left > locationObj.right) {
      // 오른쪽손이 더 가까운 경우 = 오른손으로 누른다.
      answer += 'R';
      current.right = numbers[i];
    } else {
      // 왼쪽손이 더 가까운 경우 = 왼손으로 누른다.
      answer += 'L';
      current.left = numbers[i];
    }
      }
    }
  }
  return answer;
}

▷ reduce 매서드 사용 풀이

// const leftNumbers = [1, 4, 7]; // 왼손 엄지손가락을 이용해 눌러야 할 키패드들
// const rightNumbers = [3, 6, 9]; // 오른손 엄지손가락을 이용해 눌러야 할 키패드들
const [leftNumbers, rightNumbers] = [
  [1, 4, 7],
  [3, 6, 9],
];

function solution(numbers, hand) {
  // 현재 손가락의 위치 (왼손가락, 오른손가락) = 어떤 키패드에 위치하고 있는지
  const current = {
    left: 10, // *에 해당하는 위치값
    right: 12, // #에 해당하는 위치값
  };

  return numbers.reduce((acc, cur) => {
    // useFinger : 어떤 손가락을 이용해서 눌렀는지 ("L", "R")
    // target : 어떤 손으로 눌렀는지를 저장 ("left", "right")
    let [useFinger, target] = ['', ''];

    if (leftNumbers.includes(cur)) {
      // 왼쪽 키패드를 누른 경우
      [useFinger, target] = ['L', 'left'];
    } else if (rightNumbers.includes(cur)) {
      // 오른쪽 키패드를 누른 경우
      [useFinger, target] = ['R', 'right'];
    } else {
      // 가운데 키패드를 누른 경우
      const locationObj = Object.entries(current).reduce((acc2, cur2) => {
        cur = !cur ? 11 : cur;
        let location = Math.abs(cur - cur2[1]);

        if (location > 2) {
          // location >= 3
          // Math.trunc : 소수점 제거
          location = Math.trunc(location / 3) + (location % 3);
        }
        acc2[cur2[0]] = location;
        return acc2;
      }, {});

      // 두 손가락의 위치가 동일할 경우
      if (locationObj.left === locationObj.right) {
        [useFinger, target] = [hand === 'left' ? 'L' : 'R', hand];
      } else if (locationObj.left > locationObj.right) {
        // 오른쪽 손가락이 더 가까운 경우
        [useFinger, target] = ['R', 'right'];
      } else {
        // 왼쪽 손가락이 더 가까운 경우
        [useFinger, target] = ['L', 'left'];
      }
    }

    // 누른 손가락의 위치를 변경
    current[target] = cur;
    return acc + useFinger;
  }, '');
}

출처: 프로그래머스
출처: 코드캠프

profile
개발자 블로그 / 항상 겸손한 자세로 배우면서 성장하자 할 수 있다!

0개의 댓글