본문 바로가기
취업준비/인턴, 신입 지원 기록

2020 상반기 카카오 채용전환형 인턴 코딩테스트 1번 문제 복기

by 카펀 2020. 10. 3.

올해 5월 초에 올라왔던,

상반기 채용전환형 인턴 코딩테스트 복기입니다.

 

해당 코딩테스트 관련 카카오블로그 글: 링크

 

지금도 저는 많이 부족하지만, 저 당시에는 코딩테스트를 아예 준비한 적 없는 상태에서 경험 삼아 코딩테스트를 보았습니다.

제 코드를 보시면 굉장히 지저분해 보인다는 느낌을 받으실 겁니다.

특히 그렇게 느꼈던 부분이 solution 함수인데,

while loop 내에서 경우의 수마다 비슷한 코드를 계속 써 넣다 보니,

가독성이 떨어지고 실수가 생기기에도 좋은, 굉장히 비효율적인 코드를 작성하고 있다고 느꼈습니다.

당시엔 알면서도 그냥 진행했습니다. 이걸 도로 수정해서 제한시간 내에 더 깔끔하게 만들 자신이 없었어요 ㅠㅠ...

 

함수는 기본으로 주어진 solution 함수, 그 외에 현재 손가락 위치와 목표 번호까지의 거리를 구하는 get_distance 함수까지 총 2개 만들었습니다.

get_distance 함수의 경우 많이 줄일 수 있을 것 같고, solution 함수는 반복되는 부분이 많긴 하지만 줄이기 쉽지 않을 것 같습니다.

 

이 문제 하나를 푸는데 2시간 반 가량 걸렸던 것으로 기억합니다.

아직 갈 길이 멉니다...

 

당시에 작성한 코드:

 

#include <string>
#include <iostream>
#include <vector>
using namespace std;
int get_distance(int current, int target) {
int distance = 0;
int target_zero = target - 1; //target값을 인덱스에 맞게 변환. 예) # -> 11, 4 -> 3
if (target == 0)
target_zero = 10; //target값이 0일 경우 키패드에 맞게 변환
int position = current - 1; //현재 위치 값을 인덱스에 맞게 변환
if (current == 0)
position = 10; //0번 키의 위치 따로 계산
int keypad[4][3] = { 0 }; //방문하지 않았음 keypad[y][x]
//이상 현재 위치 및 목표 위치를 인덱스값으로 초기화
int target_x = target_zero % 3;
int target_y = target_zero / 3;
int position_x = position % 3;
int position_y = position / 3;
keypad[position_y][position_x] = 1;
//현재 위치를 방문하였다고 가정
while (keypad[target_y][target_x] == 0) { //목적지를 방문할 때까지 while문 반복
//가로, 즉 x부터 먼저 맞춥니다.
if (position_x != target_x) {
if (position_x < target_x)
position_x++;
else if (position_x > target_x)
position_x--;
}
else if ((position_x == target_x) && (position_y != target_y)) { //세로 맞춥니다
if (position_y < target_y)
position_y++;
else if (position_y > target_y)
position_y--;
}
keypad[position_y][position_x] = 1; //방문하였음
distance++; //거리값 1 추가
}
return distance;
//BFS 방법의 최소거리 계산법도 고려해 보았습니다.
}
string solution(vector<int> numbers, string hand) {
string answer = "";
int L_position = 10, R_position = 12;
//10은 *, 12는 #을 의미
//11은 0을 의미
while (!numbers.empty()) {
if (numbers.front() == 1 || numbers.front() == 4 || numbers.front() == 7) {
answer.push_back('L');
L_position = numbers.front();
numbers.erase(numbers.begin());
//숫자가 1, 4, 7일 경우, 왼손의 현재 위치를 갱신하고
//answers에 L을 하나 기록하고 numbers에서 숫자를 pop한다.
}
else if (numbers.front() == 3 || numbers.front() == 6 || numbers.front() == 9) {
answer.push_back('R');
R_position = numbers.front();
numbers.erase(numbers.begin());
//숫자가 3, 6, 9일 경우, 오른손의 현재 위치를 갱신하고
//answers에 R을 하나 기록하고 numbers에서 숫자를 pop한다.
}
else {
//나머지 경우가 숫자가 2, 5, 8, 0일 경우
int L_distance = get_distance(L_position, numbers.front());
int R_distance = get_distance(R_position, numbers.front());
//더 거리가 짧은 쪽을 기준으로,
if (L_distance < R_distance) {
answer.push_back('L');
L_position = numbers.front();
numbers.erase(numbers.begin());
}
else if (R_distance < L_distance) {
answer.push_back('R');
R_position = numbers.front();
numbers.erase(numbers.begin());
}
else {
//왼손과 오른손으로부터의 거리가 같을 경우
if (hand == "left") {
answer.push_back('L');
L_position = numbers.front();
numbers.erase(numbers.begin());
}
else {
answer.push_back('R');
R_position = numbers.front();
numbers.erase(numbers.begin());
}
}
}
//cout << answer << endl;
}
//위의 반복되는 값 추가를 함수로 따로 빼면 더 편리할 것 같습니다.
return answer;
}
int main() {
ios::sync_with_stdio(false);
vector<int> numbers;
string hand; //이상 숫자와 손 여부를 입력받을 변수 선언
do {
int temp;
cin >> temp;
numbers.push_back(temp);
} while (getc(stdin) == ' ');
getline(cin, hand);
cin.clear();
//이상 입력받은 n개의 숫자를 모두 벡터에 추가함
cout << solution(numbers, hand);
return 0;
}
view raw gistfile1.txt hosted with ❤ by GitHub

PS. 코드를 GitHub Gist 방식으로 바꾸어 보았습니다.

더 보기 좋아졌나요?

댓글