본문 바로가기
Programming Knowledge/Algorithm

[Algorithm]프로그래머스 - 대충 만든 자판(Javascript)

by SheenaKaze 2024. 9. 11.

휴대폰의 자판은 컴퓨터 키보드 자판과는 다르게 하나의 키에 여러 개의 문자가 할당될 수 있습니다. 키 하나에 여러 문자가 할당된 경우, 동일한 키를 연속해서 빠르게 누르면 할당된 순서대로 문자가 바뀝니다.

예를 들어, 1번 키에 "A", "B", "C" 순서대로 문자가 할당되어 있다면 1번 키를 한 번 누르면 "A", 두 번 누르면 "B", 세 번 누르면 "C"가 되는 식입니다.

같은 규칙을 적용해 아무렇게나 만든 휴대폰 자판이 있습니다. 이 휴대폰 자판은 키의 개수가 1개부터 최대 100개까지 있을 수 있으며, 특정 키를 눌렀을 때 입력되는 문자들도 무작위로 배열되어 있습니다. 또, 같은 문자가 자판 전체에 여러 번 할당된 경우도 있고, 키 하나에 같은 문자가 여러 번 할당된 경우도 있습니다. 심지어 아예 할당되지 않은 경우도 있습니다. 따라서 몇몇 문자열은 작성할 수 없을 수도 있습니다.

이 휴대폰 자판을 이용해 특정 문자열을 작성할 때, 키를 최소 몇 번 눌러야 그 문자열을 작성할 수 있는지 알아보고자 합니다.

1번 키부터 차례대로 할당된 문자들이 순서대로 담긴 문자열배열 keymap과 입력하려는 문자열들이 담긴 문자열 배열 targets가 주어질 때, 각 문자열을 작성하기 위해 키를 최소 몇 번씩 눌러야 하는지 순서대로 배열에 담아 return 하는 solution 함수를 완성해 주세요.

단, 목표 문자열을 작성할 수 없을 때는 -1을 저장합니다.

 

result

keymap targets result
["ABACD", "BCEFD"] ["ABCD","AABB"] [9, 4]
["AA"] ["B"] [-1]
["AGZ", "BSSS"] ["ASA","BGZ"] [4, 6]

 

문제의 요지를 간단히 설명하자면 targets에 있는 문자열 "ABCD" , "AABB"를 keymap에 있는 "ABACD", "BCEFD"가 
각 휴대폰  자판 일 때 ABACD 라는 단어를 만들어내는데에는 최소로 얼마나 걸리느냐 , " BCEFD"라는 문자를 만드는데에는 최소로 얼마나 걸리느냐를 result인 숫자 배열로 달라는 것이다. 

나는 각 targets의 각 해당 문자열에 접근해서 각 해당 문자에 min max처럼 비교해서 값을 셋팅하려고 했었다. 

function solution(keymap, targets) {
    var answer = [];
    var minIndex = 100;
    var pushCnt = 0;
   
    for(let i = 0;i<targets.length;i++) {
        for(let j = 0;j<targets[i].length;j++) {
            for(let k = 0 ; k<keymap.length;k++) {
                console.log(targets[i][j]);
                 let index = keymap[k].indexOf(targets[i][j]);
                    if(minIndex>index) {
                        minIndex = index;
                    }
            }
            console.log(minIndex);
           
            // if(minIndex === -1) {
            //     answer.push(-1);
            // } else {
            //      pushCnt += minIndex;
            // }    
        }
         // answer.push(pushCnt);
    }
   
    return answer;
}

그러나 더 이상 생각이 나지 않는다.. 뭔가 어디서부터 꼬인 것 같다. 생각이 전개되지 않았다. 

다른 사람의 풀이를 참고하여 , 복기하며 다시 작성해보았다. 요지는 이렇다. 

function solution(keymap, targets) {
    const answer = [];
    const map = {}

    for (const items of keymap) {
        items.split('').map((item, index) => map[item] = (map[item] < index+1 ? map[item] : index+1))
    }
    for (const items of targets) {
        answer.push(items.split('').reduce((cur, item) => cur += map[item], 0) || -1)
    }
    return answer;
}

const arr1 = ["ABACD", "BCEFD"];
const arr2 = ["ABCD","AABB"];

solution(arr1,arr2);

for문을 keymap과 targets을 돌린다 .

첫번째 keymap 대한 for문은 현재 각 자판의 문자열을 문자 배열로 만들고 인덱스값으로 값을 변경하여 배열을 return한다.

이 map[item]을 통해서 map 객체는 각 자판을 얼마나 쳐야 해당 문자가 나오는지를 저장하고 있다.

하여 횟수가 더 빠른 것이 있으면 더 빠른 index 값으로 바뀌게 된다.

두번째 for문에서는 targets을 돌려서 map에 가장 빠른 횟수로 해당 문자를 칠 수 있는 index값을 전부 더하여 answer 배열에 넣는다. 추후 answer 배열을 return 한다.. 간단하면서도 복잡한.. 그러면서도 문제 이해가 쉽지않다.