본문 바로가기

DEVELOP/Algorithm

[Algorithm] 2019 카카오 블라인드 테스트 문제풀이 - 오픈채팅방

반응형

[Algorithm] 2019 카카오 블라인드 테스트 문제풀이 - 오픈채팅방

문제

카카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다.

신입사원인 김크루는 카카오톡 오픈 채팅방을 개설한 사람을 위해, 다양한 사람들이 들어오고, 나가는 것을 지켜볼 수 있는 관리자창을 만들기로 했다. 채팅방에 누군가 들어오면 다음 메시지가 출력된다.

"[닉네임]님이 들어왔습니다."

채팅방에서 누군가 나가면 다음 메시지가 출력된다.

"[닉네임]님이 나갔습니다."

채팅방에서 닉네임을 변경하는 방법은 다음과 같이 두 가지이다.

채팅방을 나간 후, 새로운 닉네임으로 다시 들어간다.
채팅방에서 닉네임을 변경한다.
닉네임을 변경할 때는 기존에 채팅방에 출력되어 있던 메시지의 닉네임도 전부 변경된다.

... 중략 ...

채팅방에 들어오고 나가거나, 닉네임을 변경한 기록이 담긴 문자열 배열 record가 매개변수로 주어질 때, 모든 기록이 처리된 후, 최종적으로 방을 개설한 사람이 보게 되는 메시지를 문자열 배열 형태로 return 하도록 solution 함수를 완성하라.

프로그래머스 문제 바로가기

풀이

def solution(record):
    # 각 레코드에서 유저 아이디 및 명령어 처리
    users = {}
    messages = []
    for rec in record:

        # 문자열을 리스트로 분리
        cmd = rec.split()

        # 길이가 3일 경우 유저 입장||아이디 변경이므로 users에 추가||변경
        if len(cmd) == 3:
            users[cmd[1]] = cmd[2]

        # 메시지 원문 삽입
        messages.append([cmd[0], cmd[1]])

    # 메시지 원문 기반으로 유저가 보는 메시지 생성
    suffix = {"Enter": "님이 들어왔습니다.", "Leave": "님이 나갔습니다."}
    answer = [users[msg[1]] + suffix[msg[0]] for msg in messages if msg[0] in suffix]

    return answer

대화방에 유저가 들어오고 나가는 메시지를 출력하는 간단한 문제.

주의할 점이라고는 대화방에 들어온 적이 있는 유저의 닉네임 관리다.

제한사항이 매우 친절하다.

  • 모든 유저는 [유저 아이디]로 구분한다.
    • 유저를 관리할 Key 명시
  • 채팅방에서 나간 유저가 닉네임을 변경하는 등 잘못된 입력은 주어지지 않는다.
    • 예외 상황에 대한 고려가 줄어든다.

로직은 크게 2단계로 나누어진다.

  1. 인자로 받은 record의 처리
  2. 처리된 record를 기반으로 출력될 메시지 리스트 생성

STEP 1

먼저 문자열의 형태로 들어오는 record를 다루기 쉽도록 각 문자열을 2차원 배열의 형태로 변환한다.

파이썬의 경우 split() 함수로 공백을 기준으로 한 리스트를 생성한다.

"Enter", "Change"의 경우 원소가 3개, Leave의 경우 원소가 2개인 리스트가 반환된다.

이 경우 users에 아이디를 Key로 하여 닉네임을 Value로 저장하거나, 변경한다.

그리고 messages 리스트에 ["Enter", "아이디"] 포맷의 리스트를 추가한다.

닉네임 정보는 어차피 users에 최신화 되어있는 데이터를 써서 최종적으로 보여지는 메시지를 만들 것이기 때문에 필요없다.

STEP 2

이제 messages에 있는 데이터와 users의 아이디를 기반으로 출력될 메시지를 만들면 된다.

여러가지 방법이 있겠지만 두가지에 초점을 맞춰서 코드를 짰다.

  1. 간결성
  2. Pythonic

for문을 이용해서 좀 더 풀어서 코드를 작성해도 큰 차이는 없었겠지만 Pythonic을 좀 고려해봤다.

한글 메시지는 "Enter" 등과 1:1 대응하기 때문에 딕셔너리를 이용해봤다.

이렇게 할 경우 새로운 record가 추가돼도 딕셔너리에 쌍 한 개만 추가하면 되기 때문에 확장성이 좀 더 생길지도.

물론 시험 자체에서 이렇게 고려한 건 아니고, 포스팅 쓰기 전 리팩토링 하면서 바꿔봤다.

1번 문제인만큼 몇 줄 안 되는 코드로 풀 수 있는 문제였다.

처음으로 본 코딩 테스트의 처음으로 푼 문제.
그 당시에 정답을 맞췄는지는 모르겠다.
본격적으로 개발자가 되어야겠다고 마음먹고 한 달 남짓 되었을 때 같다.
지금이야 너무 간단하게 풀어버리니 기울기야 어쨌든 실력이 우상향 되는 것 같다.

반응형