개발/자료구조, 알고리즘

[코딩 테스트] 프로그래머스 연습 문제 - 키패드 누르기

growing-dev 2023. 5. 23. 09:31
반응형

제목과 연관된 키워드가 무조건 들어가야 한다.

 

 

프로그래머스 연습 문제 - 키패드 누르기

 

 

 

 문제 설명

 

  1. 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
  2. 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
  3. 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
  4. 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
    4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.

 

스마트폰 키패드

 

 

 

 제약 사항

 

  • numbers 배열의 크기는 1 ~1,000
  • numbers 배열 원소의 값은 0 ~9 
  • hand는 "left" 또는 "right"입니다.
  • 왼손 엄지손가락을 사용한 경우는 L, 오른손 엄지손가락을 사용한 경우는 R을 순서대로 이어 붙여 문자열 형태로 return

 

 

 

 코드

 

문제 이해는 쉽지만 실제로 구현하려고 하면 약간 생각해야 하는 문제입니다. 현재 위치를 알고 있어야 하는 문제라서 그런 것 같습니다. 저는 스마트폰의 키패드 배열을 2차원 좌표계로 생각했습니다. 그래서 왼손, 오른손의 시작 위치를 (3,0), (3,2)라고 지정하고 들어오는 숫자에 따라서 position을 변환하고 그 position을 업데이트해 나가는 방식으로 구현했습니다. 코드는 아래와 같습니다.

 

#include <string>
#include <vector>

using namespace std;
int getdistance(int *a, int *b) {
    return abs(a[0] - b[0]) + abs(a[1] - b[1]);
}
void cpy(int* a, int* b) {
    a[0] = b[0], a[1] = b[1];
}
string solution(vector<int> numbers, string hand) {
    string answer = "";
    int l_pos[2] = {3,0};
    int r_pos[2] = { 3,2 };
    int cur_pos[2];
    
    for (int i = 0; i < numbers.size(); i++) {
        int cur_num = numbers[i];
        if (cur_num == 0) cur_num = 11;
        cur_pos[0] = (cur_num - 1) / 3;
        cur_pos[1] = (cur_num - 1) % 3;
        
        if (cur_num == 1 || cur_num == 4 || cur_num == 7) {
            answer += "L"; cpy(l_pos,cur_pos);
        }
        else if (cur_num == 3 || cur_num == 6 || cur_num == 9) {
            answer += "R"; cpy(r_pos, cur_pos);
        }
        else {
            if (getdistance(l_pos,cur_pos) > getdistance(r_pos, cur_pos)) { //r이 더 가까울때
                answer += "R"; cpy(r_pos, cur_pos);
            }
            else if (getdistance(l_pos, cur_pos) < getdistance(r_pos, cur_pos)) { //l이 더 가까울때
                answer += "L"; cpy(l_pos, cur_pos);
            }
            else { //거리가 같을 때
                if (hand == "left") {
                    answer += "L"; cpy(l_pos, cur_pos);
                }
                else {
                    answer += "R"; cpy(r_pos, cur_pos);
                }
            }
        }
    }
    return answer;
}

 

 

 

 

 

 결론

 

항상 2차원 배열로 표현할 수 있는지 여부를 판단하는 게 좋은 아이디어입니다. 1차원을 2차원으로 확장하거나 2차원을 1차원으로 압축하여 효과적인 알고리즘을 만드는 경우의 문제가 종종 있습니다. 이 문제는 그 정도의 문제는 아니긴 하지만 2차원 배열 혹은 좌표를 연습해 볼 수 있는 문제인 것 같습니다.

반응형