[プログラマ]キーボードを押す


🤔 質問する


プログラマ-キーボードを押す
2020ココア実習
スマートフォンの電話キーボードの各スペースには、次の数字があります.

この電話のキーボードには、左手と右手の親指で数字を入力したいだけです.
最初の左手親指は*キーボードから始まり、右手親指は#キーボードの位置から始まり、親指を使うルールは以下の通りです.
  • 親指は上下左右4方向にしか移動できず、キーボードを動かすセル距離は1です.
  • 左側の列の3つの数字1、4、7を入力する場合は、左手親指を使用してください.
  • 右側の列の3つの数字3、6、9を入力する場合は、右手親指を使用してください.
  • の4つの数字2、5、8、0を入力する場合は、2つの親指の現在のキーボード位置に近い親指を使用します.
    4-1. 2つの親指の距離が等しい場合は、右利きは右手親指、左利きは左手親指を使用します.
  • solution関数を完了して順序番号を示す配列番号、左利きか右利きかを示す文字列番号をパラメータとすると、各番号の親指が左手か右手かを示す連続文字列形式で返されます.

    ¥2,000円制限

  • numbers配列のサイズは1000を超えません.
  • numbers配列要素の値は0または9以下の整数です.
  • 手は「左」または「右」です.
  • 「左」は左利き、「右」は右利きを表す.
    左手親指を使う場合はL、右手親指を使う場合はRを順番につなぎ、文字列で返します.
  • 💡 に近づく

  • スマートフォンのキーボードを対象形態の座標空間と見なす.
    - const keypad = { key(keypad 숫자): value([y, x]) }
  • 左手、右手で押したキーの状態を更新します.
  • 更新後の数字の位置と押す数字の位置との距離を計算します.
  • solution関数では、左列と右列について無条件に'L', 'R'と定められているので、if, else if条件に従ってanswer配列に入れる.
    中間の列については、現在入力されているnumと左右の指の位置leftPos, rightPosとの距離に基づいて、'L', 'R'の値が決定される.
    中熱時間距離の関数calcDistanceを作成した.横(x軸)、縦(y軸)の距離を算出して合算し、左手と右手のそれぞれの距離を比較して「L」または「R」を返します.このとき距離計算では負数が出ないため,Math.abs()法を用いた.距離が同じ場合、handを基準とします.calcDistance関数の戻り値をanswer配列に入れます.'L', 'R'により、leftPos, rightPosの状態も更新されます.

    🧑🏻‍💻 コード#コード#

    function calcDistance(num, leftPos, rightPos, hand) {
      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 leftDistance =
        Math.abs(keypad[num][0] - keypad[leftPos][0]) +
        Math.abs(keypad[num][1] - keypad[leftPos][1]);
      
      // 오른손 거리
      const rightDistance =
        Math.abs(keypad[num][0] - keypad[rightPos][0]) +
        Math.abs(keypad[num][1] - keypad[rightPos][1]);
      
      // 거리 비교 후 'L' 또는 'R' 리턴
      if (leftDistance > rightDistance) return 'R';
      if (leftDistance < rightDistance) return 'L';
      return hand[0].toUpperCase();
    }
    
    function solution(numbers, hand) {
      let leftPos = '*';
      let rightPos = '#';
      const answer = [];
      
      for (let i = 0; i < numbers.length; i++) {
        const num = numbers[i];
        if (num % 3 === 1) { // 키패드 왼쪽 열
          answer.push('L');
          leftPos = num;
        } else if (num % 3 === 0 && num !== 0) { // 키패드 오른쪽 열
          answer.push('R');
          rightPos = num;
        } else { // 키패드 가운데 열
          answer.push(calcDistance(num, leftPos, rightPos, hand));
          calcDistance(num, leftPos, rightPos, hand) === 'R'
            ? (rightPos = num)
            : (leftPos = num);
        }
      }
      
      return answer.join('');
    }
    
    solution([1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5], 'right'); // "LRLLLRLLRRL"

    📝 リファレンス


    Kakao Tech-2020 KACO技術開発者実習問題解説