TIL/알고리즘 공부

프로그래머스 Lv. 2 Swift 알고리즘 - 영어 끝말잇기

여의도사노비 2023. 1. 1. 21:08
728x90

기준을 세우는데 꽤나 오래 걸린 문제이다.

아직은 성공률이 높은 문제들 위주로 풀어서 그런지 풀만한데 Lv.1에 비하면 확실히 Lv.2가 더 많은 사고를 요구하는 것 같다.

 

이 문제를 풀기 위해서 필요한 기준은 3가지이다.

1. 한 번 언급된 단어가 다시 언급 됐을 경우 그 즉시 게임을 중지시키고, 마지막 단어를 언급한 플레이어가 패한다.

2. 아무도 지지 않는 결과가 나올 수 있다.

3. 앞의 단어의 마지막 글자와 뒤에 나오는 단어의 첫 번째 글자가 다를 경우 뒤에 나오는 단어를 언급한 플레이어가 패배한다.

 

 

 

이 문제를 풀면서 생각한 논리적 흐름

  1. 몇 번 플레이어, 몇 번째 게임이 진행중인가?에 대한 값은 count를 통해 단어가 언급된 총 횟수를 사람 숫자인 n으로 나누거나 나머지를 이용하여 구할 수 있다.
  2. 플레이어가 단어를 언급할 때마다 기존 words 배열에 해당 단어가 언급되었는지 확인하고 언급되지 않은 새로운 단어라면 바로 append해준다.
  3. 그리고 만약 언급된 단어가 기존에 언급되었던 단어라면 그 즉시 break를 사용하여 게임을 끝내고 당시 manNumber와 tryNumber를 기준으로 패배한 사람을 선정한다.
  4. 새로운 단어를 언급했더라도 바로 전 단어의 마지막 글자와 현재 언급된 단어의 첫 글자가 다르면 그 즉시 break를 사용하여 게임을 끝내고 당시 manNumber와 tryNumber를 기준으로 패배한 사람을 선정한다.
  5. 만약 words에 있는 단어들이 다 언급되었는데 패자가 결정되지 않았다면 count == words.count 일 것이고 그렇다면 패자가 없는 것으로 보고 [0, 0]을 반환한다.

 

 

* 코드

import Foundation

func solution(_ n:Int, _ words:[String]) -> [Int] {
    var count = 0
    var check: [String] = []
    var manNumber = 0
    var tryNumber = 0
    
    for i in words {
        if check.contains(i) {
            break
        } else {
            if check.count == 0 {
                check.append(i)
            } else {
                let checkLast = check.last
                check.append(i)
                if checkLast!.suffix(1) != check.last!.prefix(1) {
                    break
                }
            }
        }
        count += 1
        manNumber = (count % n) + 1
        tryNumber = (count / n) + 1
    }
    
    if count == words.count {
        manNumber = 0
        tryNumber = 0
    }
    
    return [manNumber, tryNumber]
}

 

 

정리(Today I Learned)

  1. 그 전에 다른 문제를 풀 때 suffix를 사용하니 시간이 엄청 오래걸려서 효율성 걱정을 많이 했다.
  2. 하지만 다행히 suffix, prefix를 사용했음에도 불구하고 시간이 오래 걸린 테스트케이스는 없었다.
  3. 조금 더 논리적으로 깔끔하게 구성할 수 있을 것 같다. 혹은 solution이 아닌 새로운 메서드를 만들어서 코드를 조금 더 깔끔하게 보이게 할 수 있을 것 같다.