본문 바로가기
알고리즘 부셔버렷/ProblemSolving

[프로그래머스] 키패드 누르기 (설명, 해결 과정, 코드 전문, c++)

by Unagi_zoso 2022. 5. 27.

 

  문제 설명

 

 

본 문제는 프로그래머스의 키패드 누르기 문제로 모바일처럼 키패드가 있을 때

1 2 3

4 5 6 

7 8 9 

* 0 #

 

1,4,7의 왼쪽은 왼쪽 손가락으로만, 3,6,9는 오른 손가락으로만 누른다고합니다. 가운데의 숫자들은

왼쪽, 오른쪽 손가락 중 더 가까운 손가락으로 누른다고 합니다. 거리가 같은 때는 매개변수인 오른손잡이인지 왼손잡이 정보를 가지고 각 각 오른손, 왼손으로 누릅니다.

 

그리고 이 손가락으로 누를 때 마다 문자열에 L, R을 적어 반환합니다.

 

 

 

  해결 과정

 

 

전 일단 이 키패드의 넘버 하나하나에  좌표를 주고 주어진 숫자배열을 따라 왼손가락, 오른손가락의 위치를 옮겼습니다.

가운데 번호에 접근을 위해 왼손가락 오른손가락을 비교할 때는 절댓값을 이용한 좌표연산으로 그 길이를 구하였습니다.

 

 

  코드 전문

 

 

#include <string>
#include <vector>
#include <unordered_map>
#include <utility>

using namespace std;

int get_dist_points(const int pnt1, const int pnt2);
int cmp_points(const int& l_pnt, const int& r_pnt, const int& goal_pnt);

unordered_map<int, pair<int, int>> nptb // numberpad_point_table 
                        {{1,{0, 3}}, {2,{1, 3}}, {3,{2, 3}}, 
                         {4,{0, 2}}, {5,{1, 2}}, {6,{2, 2}}, 
                         {7,{0, 1}}, {8,{1, 1}}, {9,{2, 1}}, 
                         {-1,{0, 0}}, {0,{1, 0}}, {-2,{2, 0}}};

string solution(vector<int> numbers, string hand) {
    string answer = "";
    int l_finger = -1;
    int r_finger = -2;    
    
    for (auto num : numbers)
    {
        if (num == 3 || num == 6 || num == 9)
        {
            answer += 'R';
            r_finger = num;
        }
        else if (num == 1 || num == 4 || num == 7)
        {
            answer += 'L';
            l_finger = num;
        }
        else
        {
            if (cmp_points(l_finger, r_finger, num) == -1) // r_finger shorter than l
            {
                answer += 'R';
                r_finger = num;
            }
            else if (cmp_points(l_finger, r_finger, num) == -2) // l_finger shorter than r
            {
                answer += 'L';
                l_finger = num;
            }
            else if (cmp_points(l_finger, r_finger, num) == -3) // same case
            {
                if (hand == "right")
                {
                    answer += 'R';
                    r_finger = num;
                }
                else if (hand == "left")
                {
                    answer += 'L';
                    l_finger = num;
                }
            }
        }
    }
    return answer;
}

int get_dist_points(const int pnt1, const int pnt2)
{
    int x_dist = abs(nptb[pnt1].first - nptb[pnt2].first);
    int y_dist = abs(nptb[pnt1].second - nptb[pnt2].second);
        
    return x_dist + y_dist;
}
    
int cmp_points(const int& l_pnt, const int& r_pnt, const int& goal_pnt)
{
    int l_pnt_dist = get_dist_points(l_pnt, goal_pnt);
    int r_pnt_dist = get_dist_points(r_pnt, goal_pnt);
    if (l_pnt_dist > r_pnt_dist) return -1;
    else if (l_pnt_dist < r_pnt_dist) return -2;
    else if (l_pnt_dist == r_pnt_dist) return -3;
}

 

 

 

 

  느낀 점 (잡설 99% , 배운점 1%(많은 편))

 

더보기

이름 짓기가 정말 어렵다는 걸 다시 한번 깨달았고  cmp_dist_points의 반환값을 어떻게 해야할지 고민을 많이 했네요. 아마 더 좋은 방법도 있지 않았을까 생각합니다. 

그리고 pair를 사용하기 위해 utility를 include 해야함을 알았습니다.

 

 

 

 

 

긴 글 읽어주셔서 감사합니다. 

부족한 점이 있다면 부디 알려주시면 감사하겠습니다.

 

댓글