알고리즘 풀이 - 오픈채팅방

picture 22

오픈채팅방

문제 링크

문제 요약

제한사항

  • record는 다음과 같은 문자열이 담긴 배열이며, 길이는 1 이상 100,000 이하이다.
  • 다음은 record에 담긴 문자열에 대한 설명이다.

    • 모든 유저는 [유저 아이디]로 구분한다.
    • [유저 아이디] 사용자가 [닉네임]으로 채팅방에 입장 - Enter [유저 아이디][닉네임] (ex. Enter uid1234 Muzi)
    • [유저 아이디] 사용자가 채팅방에서 퇴장 - Leave [유저 아이디] (ex. Leave uid1234)
    • [유저 아이디] 사용자가 닉네임을 [닉네임]으로 변경 - Change [유저 아이디][닉네임] (ex. Change uid1234 Muzi)
    • 첫 단어는 Enter, Leave, Change 중 하나이다.
    • 각 단어는 공백으로 구분되어 있으며, 알파벳 대문자, 소문자, 숫자로만 이루어져있다.
    • 유저 아이디와 닉네임은 알파벳 대문자, 소문자를 구별한다.
    • 유저 아이디와 닉네임의 길이는 1 이상 10 이하이다.
    • 채팅방에서 나간 유저가 닉네임을 변경하는 등 잘못 된 입력은 주어지지 않는다.

Input

  • 채팅방에 들어오고 나가거나, 닉네임을 변경한 기록이 담긴 문자열 배열 record

output

  • 모든 기록이 처리된 후, 최종적으로 방을 개설한 사람이 보게 되는 메시지를 문자열 배열 형태로 return

해결방법

  • 유저의 nickname을 DB 형태로 관리
const print = (row, db) => {
  switch (row.method) {
    case 'Enter':
      return `${db.get(row.id)}님이 들어왔습니다.`
    case 'Leave':
      return `${db.get(row.id)}님이 나갔습니다.`
  }
}
function solution(record) {
  const _record = record.map(row => {
    const splited = row.split(' ')
    return { method: splited[0], id: splited[1], nickname: splited[2] }
  })
  const userDb = new Map() // uid : nickname
  _record.forEach(r => {
    if (r.nickname) userDb.set(r.id, r.nickname)
  })
  return _record.filter(r => r.method !== 'Change').map(r => print(r, userDb))
}

리팩토링

  • Destructuring assignment 사용
  • 변수명 변경
const postfix = {
  Enter: '님이 들어왔습니다.',
  Leave: '님이 나갔습니다.',
}

function solution(record) {
  const _record = record.map(row => {
    const [method, id, nickname] = row.split(' ')
    return { method, id, nickname }
  })

  const db = new Map() // uid : nickname
  _record.forEach(r => {
    if (r.nickname) db.set(r.id, r.nickname)
  })

  return _record
    .filter(r => r.method !== 'Change')
    .map(r => `${db.get(r.id)}${postfix[r.method]}`)
}

Written by@박대성

독서와 지식관리에 관심이 많은 개발자

GitHub