티스토리 뷰

반응형

프로그래머스 lvl2의 문제 다 풀어보기에서 젤 첫 문제는

2019년에 카카오 블라인드 테스트에 나왔던 카카오톡 오픈채팅방 문제이다.

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

 

코딩테스트 연습 - 오픈채팅방

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

programmers.co.kr

 

문제 설명은 다음과 같습니다.

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

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

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

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

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

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

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

예를 들어, 채팅방에 "Muzi"와 "Prodo"라는 닉네임을 사용하는 사람이 순서대로 들어오면 채팅방에는 다음과 같이 메시지가 출력된다.

"Muzi님이 들어왔습니다."
"Prodo님이 들어왔습니다."

채팅방에 있던 사람이 나가면 채팅방에는 다음과 같이 메시지가 남는다.

"Muzi님이 들어왔습니다."
"Prodo님이 들어왔습니다."
"Muzi님이 나갔습니다."

Muzi가 나간후 다시 들어올 때, Prodo 라는 닉네임으로 들어올 경우 기존에 채팅방에 남아있던 Muzi도 Prodo로 다음과 같이 변경된다.

"Prodo님이 들어왔습니다."
"Prodo님이 들어왔습니다."
"Prodo님이 나갔습니다."
"Prodo님이 들어왔습니다."

채팅방은 중복 닉네임을 허용하기 때문에, 현재 채팅방에는 Prodo라는 닉네임을 사용하는 사람이 두 명이 있다. 이제, 채팅방에 두 번째로 들어왔던 Prodo가 Ryan으로 닉네임을 변경하면 채팅방 메시지는 다음과 같이 변경된다.

"Prodo님이 들어왔습니다."
"Ryan님이 들어왔습니다."
"Prodo님이 나갔습니다."
"Prodo님이 들어왔습니다."

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

 

일단 공백으로 문자열이 나눠지니까 split()을 사용해서 값을 나누고

문제를 보고 Map 자료구조를 사용해 uid와 nickName을  Key와 value로 저장하면 되겟다고 생각했다.


전체 조회를 통해 Map에 값들을 저장후, 다시 전체 조회를 통해 key값을 value로 replace() 해버리면 되겟구나..!  생각해서 아래의 코드대로 진행했다. 

function solution(record) {
    var answer = [];
    let user = new Map();
    let userList = [];
    for(let i=0;i<record.length;i++){
        let splitArray = record[i].split(' ');
        let sentence = '';
    
        if(splitArray[0]=='Enter'){
            sentence = `${splitArray[1]}님이 들어왔습니다.`
            user.set(splitArray[1],splitArray[2]);
            userList.push(splitArray[1])
        }
        else if(splitArray[0]=='Leave'){
            sentence = `${splitArray[1]}님이 나갔습니다.`
        }
        else if(splitArray[0]=='Change'){
            user.set(splitArray[1],splitArray[2]);
    }
        if(sentence!='') answer.push(sentence)
  
    }
  
    let temp = [];
    for(let i=0; i<answer.length;i++){
        for(let j=0; j<userList.length;j++){
            if(answer[i].includes(userList[j])){
                temp.push(answer[i].replace(userList[j],user.get(userList[j])))
                break;
            }
        }
    }
    answer = temp;
  
   
    
    return answer;
}

테스트 케이스를 통과해서 오.. 쉬운데 하고 채점을 실행했다..

 

 

결과는 참혹.. 역시 카카오 문제가 이렇게 쉬울리가 없지.. 하면서 다시 코드 분석에 들어갔다.


일단 시간초과가 뜬것을 보고, 더 효율적으로 하기위해서, 고민해본결과 Map을 사용할 필요가 없었다..(그냥 Map이 쓰고싶었나보다) 유저 리스트를 저장하려고 선언한 배열에, index값을 uid로 value를 nickName으로 지정하면 바로 해결된 문제였다..

그럼 이제 Map의 아이템들을 갖고 오기 위한 반복문 사용도 없어지고

1. 값 저장을 위한 반복문

2. 저장된 값으로 출력을 위한 반복문

아래와 같이 간단한 코드가 완성되었다.

 

function solution(record) {
    var answer = [];
    let userList = []; //UserID저장
    
    //Input 읽으면서 Enter 및 Change 경우 아이디 저장
    for(let i=0;i<record.length;i++){
        let splitArray = record[i].split(' ');
        if(splitArray[0]=='Enter'||splitArray[0]=='Change'){     
             userList[splitArray[1]] = splitArray[2]
        }
    }
    
    
    //다시 Input 읽으면서 문장 최종 ID로 완성
    for(let i=0;i<record.length;i++){
        let splitArray = record[i].split(' ');
        if(splitArray[0]=='Enter'){     
            answer.push(`${userList[splitArray[1]]}님이 들어왔습니다.`)
        }
        else if(splitArray[0]=='Leave'){
            answer.push(`${userList[splitArray[1]]}님이 나갔습니다.`)
        }
    }  
    return answer;
}

 

결과는 통과!

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함