알고리즘/프로그래머스

[프로그래머스/Swift] 오픈채팅방

녕이 2023. 1. 5. 15:44
728x90

 

https://school.programmers.co.kr/learn/courses/30/lessons/42888

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

구현문제였다. 간단히 풀 수 있는 문제!

 

Message 구조체를 만들어줬다. 안에는 아이디와 Enter인지 Leave인지에 대한 부울 변수가 저장된다.

이 구조체는 나중에 출력해줄 때 사용하려고 만들었다.

누가 들어왔는지 여기에 넣어주고 모든 record를 확인하고 난 뒤에 이 메시지 배열 기록을 보고 출력!

dictionary에는 오픈채팅방에 들어온 사람들을 기록하는 것이다. 닉네임을 바꿨다면 여기서 value값을 바꿔주면 된다.

 

1. record 돌면서 split

2. ENTER라면 dictionary에 [id:nickname] 넣기

    messages에 Message(id:isEnter:true) 객체 넣기

3. Leave라면 messages에 Message(id:isEnter:false) 객체 넣기

4. Change라면 dictionary[id] = nickname 업데이트

----------------------

5. messages 돌면서 isEnter == true라면 들어왔다고 출력, 아니면 나갔다고 출력

 

struct Message {
    let id: String
    let isEnter: Bool
}

func solution(_ record:[String]) -> [String] {
    var messages = [Message]()
    var dictionary = [String: String]() //id:nickname
    for rec in record {
        let m = rec.split(separator: " ").map{ String($0) }
        if m[0] == "Enter" {
            dictionary[m[1]] = m[2]
            messages.append(Message(id: m[1], isEnter: true))
        }else if m[0] == "Leave" {
            messages.append(Message(id: m[1], isEnter: false))
        }else {
            dictionary[m[1]] = m[2] //update nickname
        }
    }
    return messages.map { $0.isEnter ? "\(dictionary[$0.id]!)님이 들어왔습니다." : "\(dictionary[$0.id]!)님이 나갔습니다." }
}

 

 

 


 

나름 빠르게 잘 짠 코드라고 생각했는데 그래도 다른 사람의 코드를 확인해 보자!^^

좋아요를 14개나 받은 코드인데, 한눈에 보고 이해가 되지 않아서 가져와서 분석해보기로 했다.

여러 사람들이 유사한(??) 코드를 짰는데 그중에서도 변수명을 잘 작성한 코드를 가져와봤다.

func solution(_ record:[String]) -> [String] {

    let action = ["Enter" : "님이 들어왔습니다.", "Leave" : "님이 나갔습니다."]
    var nickName = [String:String]()

    record.forEach {
        let separated = $0.components(separatedBy: " ")
        if separated.count > 2 {
            nickName[separated[1]] = separated[2]
        }
    }

    return record.filter{!$0.contains("Change")}.map{(value : String) -> String in
        /// map의 value에 record에서 받아온 "Enter uid1234 Muzi" 이런 문장을 담는다.
        let separated = value.components(separatedBy: " ")
        let newString = nickName[separated[1]]! + action[separated[0]]!
        return newString
    }
}

 

nickName이 내가 정의한 dictionary와 동일. (변수명 짓기 귀찮아서 그냥 dictionary라고 했는데 실제로는 이렇게 하면 안 됨ㅠ)

아... 그냥 저 record.forEach 부분에서 Enter/Leave/Change 상관없이 id에 nickname을 업데이트해 줬다. 어차피 enter, leave는 이전 닉네임과 동일하고 change만 닉네임이 변경되니까..!!

그러고 바로 change가 아닌 애들만 필터링해서 id에 맞는 nickname + action(enter 혹은 leave에 맞는 문자열 value)

 

오오오오....

비슷한 구현이지만 나는 enter, leave, change를 모두 따로 구현했다. 좀 더 생각해 볼걸ㅎㅎ 아이고~~

 

 

 


 

 

 

C++로 풀 때는 안 풀렸는데,,, 다시 Swift로 푸니까 20분 만에 풀렸다...!!!! 세상에...

참.. 고집으로 씨쁠쁠만 했으면 골치 아팠겠다..

사실 이게 내가 성장한 것인지 언어문제인지 모르겠다ㅋㅋㅋㅋㅋㅋㅋ

 

728x90