관리 메뉴

개발이야기

[TIL] 카카오 코드 페스티벌 2019 문제 풀이 본문

Today I Learned /TIL

[TIL] 카카오 코드 페스티벌 2019 문제 풀이

안성주지몬 2018. 9. 28. 19:00

안녕하세요. 오늘은 내일 있을 라인 코딩테스트를 대비하여 올해 열렸던 카카오 코드페스티벌 2019 에 출제된 문제 두 개를 풀어봤습니다. 가장 정답률이 높았던 두 문제를 풀어서 그렇게 어렵지는 않았었습니다.


모든 문제는 프로그래머스 혹은 카카오 기술 블로그에서 확인하실 수 있습니다. 


1. 오픈채팅방 


3가지 명령에 대한 정보가 들어있는 record 배열이 들어오면 배열에 들어있는 정보를 적절히 처리하여

최종 결과가 담긴 배열을 return 해주는 함수를 구현하는 문제였습니다.


문자열 처리를 깔끔하게 하기 위해서 파이썬을 주로 이용하려고 하였고 이 문제 역시 파이썬으로 풀었습니다.

해당 uid에 대해서 아이디가 변하는 것을 처리하기 위해서 어떻게 해줘야 하나 고민을 하다가 dict 자료형을 이용하니 굉장히 쉽게 풀렸던 문제였습니다.


<dict 예제> 




dict을 이용하면 딕셔너리 자료형처럼 사용할 수 있습니다. 문자열을 키 값 혹은 인덱스 값처럼 사용하여 쉽게 접근할 수 있습니다.

처음 저는 리스트를 사용하여 uid에서 정수형 값만 따와서 처리를 해주려다가 list 범위를 초과해버리는 에러가 발생하였는데요.

dict을 사용하니 크기와 인덱스 접근 방법에 대한 고민이 해결되어 쉽게 풀 수 있었습니다.


<코드 - Python>


def solution(record):
answer = []
database = {}
for word in record:
temp = word.split(' ')
command = temp[0]
if command == "Enter":
database[temp[1]] = temp[2]
elif command == "Change":
database[temp[1]] = temp[2]
for word in record:
temp = word.split(' ')
target = database[temp[1]]
command = temp[0]
if command == "Enter":
target += "님이 들어왔습니다."
elif command == "Leave":
target += "님이 나갔습니다."
else:
continue
answer.append(target)
return answer


코드를 간단히 설명해보겠습니다.

첫 번째 for문은 파라미터로 전달 받은 record 배열에서 각각의 명령 문자열을 공백을 기준으로 쪼갭니다.

이렇게 쪼개진 문자열은 명령어에 따라서 값이 달라지게 되는데요.

"Enter", "Change" 명령은 uid 값과 name 값을 가지고 있습니다. 따라서 record 배열을 한 번 미리 돌면서 각각의 uid에 해당하는 최종 name 값을 database set 자료형에 넣어주게 됩니다.

그 후 다시 record 배열을 돌면서 answer 배열에 저장되는 "Enter", "Leave" 명령을 만나면 answer 배열에 해당하는 문자열을 저장시켜줍니다.  이렇게 저장된 answer 배열을 반환해주면 구현이 완료됩니다.


C++을 이용해서 구조체로 풀려고 처음에는 시도해보고 python 리스트나 딕셔너리를 이용하려 하였지만 몇몇 한계점이 있어서 다시 python에 set자료형을 사용하니 굉장히 쉽게 풀 수 있었습니다.



2. 실패율


게임의 각 스테이지당 실패율을 구하는 문제입니다. 실패율은 해당 스테이지에 머무르고 있는 사람 / 해당 스테이지를 풀었던 사람으로 구할 수 있습니다. 이 문제 역시 문제에 나온 조건만 유심히 확인한다면 쉽게 구현할 수 있던 문제였습니다.


<코드 - C++>


#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct Point {
    int idx;
    double value;
};
bool cmp(Point &a,Point &b) {
    if (a.value > b.value) {
        return true;
    }
    else if (a.value == b.value) {
        return a.idx < b.idx;
    }
    else
        return false;
}

vector<int> solution(int N, vector<int> stages) {
    vector<int> answer;
    Point failrate[505];
    int level[505];
    for (int i = 0;i<=N+1;i++) level[i] = 0;
    for (int i = 0;i<stages.size();i++) {
        int v = stages[i];
        level[v]++;
    }
    int total = stages.size();
    for (int i = 1;i <= N;i++) {
        int stay = level[i];
if (stay == 0){
failrate[i - 1].idx = i, failrate[i - 1].value = 0.0;
}
else{
        failrate[i - 1].idx = i, failrate[i - 1].value = (double) stay / (double) total;
}
total -= stay;
    }
    sort(failrate, failrate + N, cmp);
    for (int i = 0;i<N;i++) {
        answer.push_back(failrate[i].idx);
}
    return answer;
}


저는 vector 자료형 대신 구조체를 이용하여 문제를 풀었습니다. (저는 개인적으로 구조체가 친숙하더라구요)

코드를 설명해보겠습니다.

먼저 스테이지를 나타내는 idx 와 해당 스테이지에 실패율을 저장할 value값이 포함된 구조체를 선언해줍니다. 

다음 구조체를 내림차순, 값이 같을 시 idx 값이 작은 값이 앞에 들어갈 수 있게 sort 함수에 매개변수로 전달할 cmp 함수를 선언해줍니다.

이후 for문을 돌면서 각각의 스테이지에 머물러 있는 사용자가 몇명이 있는지 level 배열에 저장을 시켜줍니다.

총 사용자는 매개변수로 전달받은 stages 배열의 크기와 같습니다. 이 과정을 마친 후 stage 크기 만큼 for 문을 돌면서 각 스테이지 별 실패율을 저장해줍니다. 문제의 조건에서 해당 스테이지에 유저가 없을시 실패율은 0이라고 명시되어 있으므로 if 문을 통해 이 조건을 처리해줍니다. 이후 실패율을 구하고 answer vecotr에 정렬된 값을 넣어주어 구현하면 됩니다. 



Comments