iyOmSd/Title: Algorithm풀이

[Swift Algorithm] 42860 조이스틱 (프로그래머스)

냄수 2021. 2. 19. 18:43
반응형

programmers.co.kr/learn/courses/30/lessons/42860

 

코딩테스트 연습 - 조이스틱

조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다. ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA 조이스틱을 각 방향으로 움직이면 아래와 같습니다. ▲ - 다

programmers.co.kr

풀었던 문제를 또 풀어봤는데... 못풀었어요 ㅠ..

후...

Level2라하지만 2가 아닌거같구요...

 

좌로가는경우

우로가는경우를 각각 검사해주는 로직으로 풀엇지만

ABABAAAAAB 와 같은 경우에는 도중에 되돌아가는게 이득이기때문에 이런 예외케이스를 통과하지못했어요

 

더 효율적으로 풀기위해 아래와같이 풀었어요

 

풀이방법

위아래로 알파벳을 체크하는 것은 좌우의 이동에 영향을 받지않아요

먼저 알파벳을 체크하는 로직을 구현한뒤에

 

좌우로 움직이는경우를 체크하는데

우로 움직이던 좌로 움직이던 한방향으로만간다면 문자열의수 - 1 칸을 이동하구요

도중에 돌아가는경우에만 달라지겠죠

도중에 돌아가는경우는 현재 검사중인 문자열의 위치가 i 라면

2*i 만큼은 왓다 갓다하는 거리가 되겠죠

 

A가 연속적인 경우를 체크하고 

되돌아갔을때의 거리와 한방향으로만 갔을때의 거리를 비교해요

 

private func solutionP42860(_ name:String) -> Int {
    let aValue = 65
    let zValue = 90
    let name = name.map{ $0 }
    
    func stickUpDown(c: Character) -> Int {
        let ascii = Int(c.asciiValue!)
        let front = ascii - aValue
        let back = zValue + 1 - ascii
        return min(front, back)
    }
    
    // 위아래는 좌우의 이동과 상관이 없음 먼저 더해줌
    var result = 0
    for i in 0..<name.count {
        result += stickUpDown(c: name[i])
    }
    
    // 좌우로 움직이는경우는 한방향 또는 도중에 돌아가는경우이고 한방향으로갈시에는 문자열 수 - 1 과 같음
    var count = name.count - 1
    for i in 0..<name.count {
        if name[i] != "A" {
            var nextIndex = i + 1
            // 연속된 A가 많으면 되돌아 가는경우 검사
            while nextIndex < name.count && name[nextIndex] == "A" {
                nextIndex += 1
            }
            // 지금까지 온거리 * 2 -> 왓다가 되돌아가는경우
            // 문자열수 - nextIndex -> 끝나는 마지막 인덱스까지의 거리
            let move = i * 2 + name.count - nextIndex
            count = min(move, count)
        }
    }
    
    print(result+count)
    return result+count
}
반응형