[프로그래머스] 키패드 누르기



Programmers - [카카오 인턴] 키패드 누르기




사용 언어 - C++

소요 시간 - 약 39분




문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/67256




문제 요약

  1. 초기에 왼손은 키패드의 * 칸에, 오른손은 키패드의 # 칸에 위치
  2. 왼쪽 열은 왼손, 오른쪽 열은 오른손, 가운데 열은 가까운 손 우선, 거리가 같다면 왼/오른손잡이에 따라 사용




최종 코드

#include <string>
#include <vector>

using namespace std;

string solution(vector<int> numbers, string hand) {
    string answer = "";
    int leftPos = 10;
    int rightPos = 12;
    //키패드 이동 한 칸은 거리 1. 대각선이면 거리 2. 루트 2 아님.
    //왼쪽열 147 누를 때는 왼손, 오른쪽 369 누를 때는 오른손
    //가운데 2580은 가까운 손가락. 거리가 같다면 왼손잡이는 왼손, 오른손잡이는 오른손
    
    //현재 손의 위치를 알아야 함
    //각 손의 현재 위치와 다음 번호와의 거리를 알아야 함
    
    //  1  2  3
    //  4  5  6
    //  7  8  9
    // 10 11 12
    
    for(int number : numbers)
    {
        if(number == 1 || number == 4 || number == 7)
        {
            answer += "L";
            leftPos = number;
        }
        else if(number == 3 || number == 6 || number == 9)
        {
            answer += "R";
            rightPos = number;
        }
        else //2580일 때
        {
            //잠시 M으로 두고
            //answer += "M";
            
            //거리 구하는 방법
            //왼손 4, 오른손 3, 숫자 8일 때
            //거리 : 왼손 2, 오른손 3
            //행의 차이 + 열의 차이
            
            //이동할 숫자보다 현재 손의 위치가 왼쪽일 경우 행의 차이
            //이동할 숫자보다 현재 손의 위치가 오른쪽일 경우 열의 차이
            //: (현재 손의 위치 - 이동할 숫자) / 3
            
            //이동할 숫자보다 현재 손의 위치가 오른쪽일 경우 행의 차이
            //이동할 숫자보다 현재 손의 위치가 왼쪽일 경우 열의 차이
            //: (현재 손의 위치 - 이동할 숫자) % 3
            
            //1. 0은 11로 둔다
            if(number == 0) number = 11;
            
            //2. 각 손 별 거리 계산
            int leftDistance = abs((leftPos - number) / 3) + abs((leftPos - number) % 3);
            int rightDistance = abs((rightPos - number) / 3) + abs((rightPos - number) % 3);
            
            //3. 손 별 거리 비교. 손의 위치 저장하는 거 까먹지 말기
            if(leftDistance < rightDistance)
            {
                answer += "L";
                leftPos = number;
            }
            else if(rightDistance < leftDistance)
            {
                answer += "R";
                rightPos = number;
            }
            else
            {
                if(hand == "left")
                {
                    answer += "L";
                    leftPos = number;
                }
                else
                {
                    answer += "R";
                    rightPos = number;
                }
            }
        }
    }
    
    
    return answer;
}




트러블 슈팅

  • 가운데 열에서 손을 사용했을 때의 위치를 저장하지 않아 왼쪽/오른쪽 열에서의 위치가 마지막으로 저장되어 거리를 계산하는데 문제 발생
  • 마지막 손의 위치와 다음 번호와의 거리를 계산함에 있어 행과 열의 차이를 계산하는데, 딱 행의 차이, 열의 차이로 나누어 계산하려고 하여 적절한 수식을 찾는데 어려움을 겪음
    • 두 가지 수식을 세웠는데, 이 수식들이 각각 특정 경우에 따라 행의 차이, 열의 차이를 번갈아가며 수행이 가능하다는 것을 찾음. 이로 해결




해결 과정

  1. 현재 손의 위치 저장
  2. 손의 위치와 다음 번호와의 거리 저장
  3. 거리에 따라 다음에 어떤 손을 사용할지를 결정
  4. 손을 사용한 후 다시 손의 위치 저장




문제 풀이 후 소감

  • 자잘한 실수가 한 번씩 나오는데, 조금 더 꼼꼼하게 봐야할 것 같음. 대입인 경우에 ==을 사용한 실수(좀 치명적…)
  • 특정 경우에 생각하는 시간이 너무 길어짐. 이런 생각도 조금 단계별로 해보는 것도 좋을지도?
  • 확실히 코드 짜는 시간보다는 생각하는 시간이 길어졌지만, 이번엔 되려 생각하는 시간이 너무 길었던 것 같은 기분이 듬. 적당히 생각한 후에 코드로 짜보고 다시 생각하는 시간을 가지는 것이 좋을듯함