알고리즘/프로그래머스

[카카오 인턴] 키패드 누르기 (c++, 파이썬)

흰싸라기 2022. 7. 27. 20:35

 

https://school.programmers.co.kr/learn/courses/30/lessons/67256

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

[문제풀이 전]

우선 거리계산은 숫자로 하면 될 것 같아서 * = 10, 0 = 11, # = 12로 수정해서 문제를 풀었다

문제에 나온 설명대로 코드를 짜고 거리 계산하는 법만 고민하면 쉽게 풀릴 것 같았다 

거리 계산은 뭔가 규칙이 있어서 식으로 정리할 수 있을 것 같아 보다가, 이동하는 것을 아래와 같이 정리할 수 있었고

← : -1, ↑ : -3, ↓ : +3, → : +1

이를 이용해 문제를 풀 수 있었다

 

[문제풀이]

#include <string>
#include <vector>
#include <cstdlib>

using namespace std;

string solution(vector<int> numbers, string hand) {
    string answer = "";
    int lhand = 10; //*
    int rhand = 12; //#
    
    for(int i=0 ;i<numbers.size(); i++){
        int cnum = numbers[i];
        
        if(cnum == 1 || cnum == 4 || cnum == 7){
            lhand = cnum;
            answer += "L";
        }
        else if(cnum == 3 || cnum == 6 || cnum == 9){
            rhand = cnum;
            answer += "R";
        }
        else { // 2, 5, 8, 9 
            cnum = (cnum==0)? 11:cnum;
            //거리 계산
            int dl = abs(lhand-cnum)/3 + abs(lhand-cnum)%3;
            int dr = abs(rhand-cnum)/3 + abs(rhand-cnum)%3;
            
            
            if(dl<dr){ // 왼손이 가까운 경우
                lhand = cnum;
                answer += "L";
            }
            else if(dl==dr){ // 거리가 같은 경우
                if(hand == "left"){
                    lhand = cnum;
                    answer += "L";
                }
                else {
                    rhand = cnum;
                    answer += "R";
                }
            }
            else{ // 오른손인경우
                rhand = cnum;
                answer += "R";
            }
        }
    }
    
    return answer;
}
cnum = numbers[i] 입력해야하는 숫자
cnum = (cnum==0)? 11:cnum;
//거리 계산
int dl = abs(lhand-cnum)/3 + abs(lhand-cnum)%3;
int dr = abs(rhand-cnum)/3 + abs(rhand-cnum)%3;
계산을 위해 0인 경우 11로 변경
키패드는 ∓3,∓1로 이동한다. 따라서, 3으로 나누었을 때 몫과 나머지를 더하면 거리가 된다.
- 이때 좌우 이동은 한번만 가능하기 때문에 거리가 3의 배수가 될 수 없어 고려안해도 됨

 

[comment]

키패트간 거리를 계산하는 규칙 찾는 문제였던 것 같다. 헷갈렸던 부분이 나머지가 +2가 되기도하고 +1이 되기도 해서 규칙을 찾고도 성립한다고 확실할 수 없었는데, 생각하다보니 +,-가 섞여있어서 그랬던 것이었다. 그래서 두개가 섞인 경우에는 몫이 -1 되는 만큼 나머지에서 +1이 되어서 결론적으로는 거리를 구할 수 있었던 것이었다. 

1단계라 비교적 쉽게 풀 수 있었다. 그리고 파이썬에 있는 함수를 쓰면 코드를 더 단순하게 짤 수 있을 것 같아서 파이썬으로도 풀어볼 예정이다. 

+) 함수 추가로 코드 정리  

#include <string>
#include <vector>
#include <cstdlib>

using namespace std;

void useHand(int num, int& xhand, string hand, string& answer){
    xhand = num;
    answer += (hand=="left")? "L":"R";
}

string solution(vector<int> numbers, string hand) {
    string answer = "";
    int lhand = 10; //*
    int rhand = 12; //#
    
    for(int i=0 ;i<numbers.size(); i++){
        int cnum = numbers[i];
        
        if(cnum == 1 || cnum == 4 || cnum == 7)
            useHand(cnum, lhand, "left", answer);
        
        else if(cnum == 3 || cnum == 6 || cnum == 9)
            useHand(cnum, rhand, "right", answer);
        
        else{
            cnum = (cnum==0)? 11:cnum;
            int dl = abs(lhand-cnum)/3 + abs(lhand-cnum)%3;
            int dr = abs(rhand-cnum)/3 + abs(rhand-cnum)%3;
            
            if(dl<dr) useHand(cnum, lhand, "left", answer);
            
            else if(dl==dr && hand =="left")
                useHand(cnum, lhand, "left", answer);
            
            else useHand(cnum, rhand, "right", answer);
        }
    }
    return answer;
}

+) 파이썬으로 

def solution(numbers, hand):
    answer = ''
    key_left = [1, 4, 7]
    key_right = [3, 6, 9]
    
    lhand = 10;
    rhand = 12;
    
    for num in numbers :
        if num in key_left:
            answer += 'L'
            lhand = num
        elif num in key_right:
            answer += 'R'
            rhand = num
        else:
            num = num=11 if num==0 else num
            dl = abs(lhand-num)//3 + abs(lhand-num)%3
            dr = abs(rhand-num)//3 + abs(rhand-num)%3
            
            if dl<dr:
                answer += 'L'
                lhand = num
            elif dl==dr and hand == "left":
                answer += 'L'
                lhand = num
            else:
                answer += 'R'
                rhand = num
    
    return answer
  • python 문법(c랑 차이점)
    • for 변수 in [배열이름] : 배열의 원소를 하니씩 변수에 대입
    • if 변수 in [배열] : 변수가 배열에 포함되는지
    • // : 파이썬에서는 몫을 구할 때 //로 쓴다