[プログラマー]キーボード-Javascript


問題の説明


キーボードを押す


スマートフォンの電話キーボードの各スペースには、次の数字があります.

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

    せいげんじょうけん

  • numbers配列のサイズは1000を超えません.
  • numbers配列要素の値は0または9以下の整数です.
  • 手は「左」または「右」です.
  • 「左」は左利き、「右」は右利きを表す.
  • 左手親指を使用する場合はL、右手親指を使用する場合はRとなり、順番に接続され、文字列形式で返されます.

    I/O例


    ||numbers||hand||result||
    ||[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"||

    に答える

    function solution(numbers, hand) {
        
        // 위치 찾아주는 함수
        function findKey(key) {
            let keypad = [[1, 2, 3], [4, 5, 6], [7, 8, 9], ['*', 0, '#']];
            for (let i = 0; i < 4; i++) {
                for (let j = 0; j < 3; j++) {
                    if (keypad[i][j] === key) {
                        return [i, j];
                    }
                }
            }
        }
        
        var answer = '';
        let left = '*';
        let right = '#';
        for (let i of numbers) {
            if (i === 1 || i === 4 || i === 7) {
                answer += 'L';
                left = i;
            }else if (i === 3 || i === 6 || i === 9) {
                answer += 'R';
                right = i - 2;
            }else {
                let r = findKey(right);
                let l = findKey(left);
                let middle = findKey(i);
                // 손위치와 눌러야할 키패드 거리 구하기
                let rr = Math.abs(r[0] - middle[0]) + Math.abs(r[1] - middle[1]);
                let ll = Math.abs(l[0] - middle[0]) + Math.abs(l[1] - middle[1]);
                if (rr === ll) { // 거리가 같다면 오른손잡이 -> 'R', 왼손잡이 -> 'L'
                    hand === 'right' ? (right = i, answer += 'R') : (left = i, answer += 'L');
                }else if(rr > ll) { // 오른손의 거리가 더 멀다면
                    answer += 'L';
                    left = i;
                }else { // 왼손의 거리가 더 멀다면
                    answer += 'R';
                    right = i;
                }
            }
        }
        
        return answer;
    }
    まずfindKey関数を定義してキーボードの位置を特定し、1、4、7を左手で押してその位置に移動し、3、6、9を右手で押してその位置に移動します.
    中間2,5,8,0の場合,findKey関数により右手と左手および中間ボタンの位置を見つけ,それぞれ右手と中間ボタンの距離,左手と中間ボタンの距離を求める.
    距離が同じなら、右利きの右手が移動し、左利きの左手が移動します.
    右手の距離がもっと遠くなると左手が移動し、左手の距離がもっと遠くなると右手が移動します.

    他人の解答

    function solution(numbers, hand) {
        
        function dis(num, lH, rH, pos, hand){
        const lD = Math.abs(pos[lH][0] - pos[num][0]) + 
            Math.abs(pos[lH][1] - pos[num][1])
        const rD = Math.abs(pos[rH][0] - pos[num][0]) + 
            Math.abs(pos[rH][1] - pos[num][1])
        
        if (lD === rD) return hand === 'left' ?  'L' : 'R';
        return lD < rD ? 'L' : 'R'
    }
    
        const pos = {
            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]
        };
        var lH = '*', rH = '#';
        var result = ''
        for (var num of numbers){
            if (num % 3 === 1){
                result += 'L';
                lH = num;
            }
            
            else if (num !==0 && num % 3 === 0){
                result += 'R';
                rH = num;
            }
            else{
                result += dis(num, lH, rH, pos, hand)
                result[result.length-1] === 'L'? lH = num : rH = num
            }
        }
    
        return result;
    }

    コードの説明


    (1)posに座標化された1~#のオブジェクトを作成する.
    (2)左手と右手の位置を表すlh,rh変数をそれぞれ「*」,「#」に初期化する.
    (3)数字の長さでドアで繰り返す.
    1、4、7(num%3=1)の場合、Lを追加してlH位置をリフレッシュします.
    3、6、9(num%3==0、0を除く)の場合、Rを追加してrHの位置をリフレッシュします.
    この2つの場合でない場合、dis関数を使用して位置決めします.
    (4)dis関数の説明:
    押すパラメータ、左手の弦の位置、右手の弦の位置、座標、左手/右手の握るかどうかを受け入れます.
    ldは左手弦位置から目標点までのx軸とy軸の距離を表し、rdは右手弦位置から目標点までのx軸とy軸の距離を表す.
    ldとrdが同じであれば左利きか右利きかを確認する.
    異なる場合、Dはより小さな手に戻ります.
    (5)返された結果がLであればlHを現在位置に更新し、RであればrHを現在位置に更新する.

    に感銘を与える


    他の多くの草が私に似ていることに驚きました.私は「よく解けた」と思っていたので、とても嬉しかったです.
    難しい問題ではありませんが、私には少し時間がかかる問題です.
    しかし、このような自信があれば、手書きで符号化しながら解答すれば、どんな問題も解決できる.