대충 만든 자판 [프로그래머스 Lv1]

hyo·2023년 3월 16일
0

코딩테스트 준비

목록 보기
4/8
post-thumbnail

대충 만든 자판 (프로그래머스 Lv1)

문제설명

휴대폰의 자판은 컴퓨터 키보드 자판과는 다르게 하나의 키에 여러 개의 문자가 할당될 수 있습니다. 키 하나에 여러 문자가 할당된 경우, 동일한 키를 연속해서 빠르게 누르면 할당된 순서대로 문자가 바뀝니다.
예를 들어, 1번 키에 "A", "B", "C" 순서대로 문자가 할당되어 있다면 1번 키를 한 번 누르면 "A", 두 번 누르면 "B", 세 번 누르면 "C"가 되는 식입니다.
같은 규칙을 적용해 아무렇게나 만든 휴대폰 자판이 있습니다. 이 휴대폰 자판은 키의 개수가 1개부터 최대 100개까지 있을 수 있으며, 특정 키를 눌렀을 때 입력되는 문자들도 무작위로 배열되어 있습니다. 또, 같은 문자가 자판 전체에 여러 번 할당된 경우도 있고, 키 하나에 같은 문자가 여러 번 할당된 경우도 있습니다. 심지어 아예 할당되지 않은 경우도 있습니다. 따라서 몇몇 문자열은 작성할 수 없을 수도 있습니다.
이 휴대폰 자판을 이용해 특정 문자열을 작성할 때, 키를 최소 몇 번 눌러야 그 문자열을 작성할 수 있는지 알아보고자 합니다.
1번 키부터 차례대로 할당된 문자들이 순서대로 담긴 문자열배열 keymap과 입력하려는 문자열들이 담긴 문자열 배열 targets가 주어질 때, 각 문자열을 작성하기 위해 키를 최소 몇 번씩 눌러야 하는지 순서대로 배열에 담아 return 하는 solution 함수를 완성해 주세요.
단, 목표 문자열을 작성할 수 없을 때는 -1을 저장합니다.

의사코드

keymap = ["ABACD", "BCEFD"], targets = ["ABCD","AABB"] -> [9,4]
targets을 먼저 이중반복문을 돌려 targets[0][0]부터 문자열을 확인한 뒤 checkStr에 할당
checkStr 문자열과 일치하는 문자열을 keymap에서 찾으려면 keymap에서 반복문으로 먼저 인덱스에 접근한뒤 indexOf('확인문자')
있는 요소들중 확인문자랑 같은 문자열이 앞쪽에 있는 요소의 인덱스 + 1 을 resultCount에 더해준다.
checkStr과 일치하는 문자열이 keymap에 없다면 -1을 resultCount에 할당하고 리턴

작성코드

function solution(keymap, targets) {
    
    const resultArr = [];
    
    for(let i = 0; i < targets.length; i++){
        let count = 0; // targets[i]의 최소 클릭 횟수
        for(let j = 0; j < targets[i].length; j++){
            // targets[i][j]의 문자열이 keymap의 요소의 문자열에 있는 요소들로만 이루어진 배열
            let checkEle = keymap.filter((el) => {
                return el.indexOf(targets[i][j]) !== -1;
            });
            // targets[i][j]의 문자열이 keymap의 요소의 문자열에 존재하지 않을때 count에 -1을 할당시키고 break 키워드로 반복문 탈출!
            if(checkEle.length === 0){
               count = -1;
               break;
            }
            // target[i][j]를 keymap의 요소마다 접근한 클릭 횟수를 나타낸 배열
            let checkEleCount = checkEle.map((el) => {
                return el.indexOf(targets[i][j]) + 1;
            });
            // checkEleCount의 클릭 횟수가 가장 최소값인 값을 reduce매서드로 빼오기.
            let comparisonCount = checkEleCount.reduce((a,b) => {
               if(a > b){
                 a = b;  
               }
                return a;
            });
            count += comparisonCount; // targets[i][j]의 최소 클릭 횟수를 count에 더해준다. 그리고 다시 targets[i][j + 1]로 반복시작.
        }
        resultArr.push(count);
    }
    return resultArr;
}

고민한부분

처음에 너무 복잡하게 코드를 생각했기 때문에 어려웠지만,
의사코드를 쓰고 코드를 쓰다보니 고차함수(map,filter,reduce)함수가 딱 떠올라서 고차함수를 써보았다.
reduce매서드의 초기값을 어떻게 줘야할지가 가장 고민이었다.
이유는 초기값을 줘버리면 가장 최소 값이 초기값으로 할당되기만 해서 문제가 되기 때문이었다.

해결방법

초기값을 주기 애매하다면 다른 방법을 써보자는 생각에
애초에 targets[i][j]가 keymap에 존재하지 않을때 count = -1 을 할당시키고 break 키워드를 써서 반복문을 탈출 시키는 방법으로 해결하였다.

profile
개발 재밌다

0개의 댓글