프로그래머스 - 조이스틱 (Lv. 2)

OQ·2022년 3월 22일
0

프로그래머스

목록 보기
24/33

문제 링크

풀이

import Foundation

func solution(_ name:String) -> Int {
    var result = 0
    var nameArr = name.map { Int(UnicodeScalar(String($0))!.value) - 65 } // A = 0, B = 1 이런식으로 값으로 변환
    
    // 전부 A일 경우의 예외처리
    var isAllA = true
    for name in nameArr {
        if name != 0 {
            isAllA = false
            break
        } 
    }
    
    if isAllA {
        return 0
    }
    
    // 조이스틱 왼/오른쪽의 경우에 소요되는 값만 계산
    var greedyVal = nameArr.count - 1   // 어느 식으로 돌아야 최선일지 찾는다.
    
    // 먼저 뒤로갔다 앞으로 갈 경우 체크
    for index in stride(from: nameArr.count - 1, to: 1, by: -1) {        
        if nameArr[index] == 0   // 지금 순번이 A인 경우이거나
        || nameArr[index - 1] != 0 {    // 다음게 A가 아닐경우 체크할 필요 없다.
            continue    
        } 
        
        // 거꾸로 갔을 때 몇번째까지 가야하는지 체크
        var moveMore = 0
        for i in 1..<index {
            if nameArr[i] == 0 {
                continue
            } else {
                moveMore = i
            }
        }
        
        var backMove = ((nameArr.count - index) * 2)
        if moveMore == 0 {  // 앞으로 다시갈 일이 없다면
            backMove = nameArr.count - index
        }
        
        let moveVal = backMove + moveMore
        if greedyVal > moveVal {
            greedyVal = moveVal
        }
    }
    
    // 먼저 앞으로 갔다 뒤로 갈 경우 체크
    for index in 0..<nameArr.count - 1 {
        if nameArr[index] == 0   // 지금 순번이 A인 경우이거나
        || nameArr[index + 1] != 0 {    // 다음게 A가 아닐경우 체크할 필요 없다.
            continue    
        } 
        
        var moveMore = 0
        for i in stride(from: nameArr.count - 1, to: index + 1, by: -1) {
            if nameArr[i] == 0 {
                continue
            } else {
                moveMore = nameArr.count - i
            }
        }
        
        var backMove = index * 2
        if moveMore == 0 {  // 뒤로 다시갈 일이 없다면
            backMove = index
        }
        
        let moveVal = backMove + moveMore
        if greedyVal > moveVal {
            greedyVal = moveVal
        }
    }
    //print(greedyVal)
    result = greedyVal
    
    // 조이스틱 위 아래의 경우에 소요되는 값만 계산
    for (index, name) in nameArr.enumerated() {
        if name > 12 {  // 조이스틱 아래쪽으로 이동하는게 빠른 경우
            result += 26 - name
        } else {    // 조이스틱 위쪽으로 이동하는게 빠른 경우
            result += name
        }
    }

    return result
}

후기

아스키코드로 변경하고 비교하는 그런 부분은 아무것도 아니다...
조이스틱을 왼쪽 오른쪽 이동을 최소화하는 방법을 찾는게 관건인 문제.
처음에는 조이스틱 앞으로 갔다 뒤로가는 경우만 생각해서 풀다가 아니라는걸 깨닫고
그 반대의 경우도 코드로 짜느라 코드 양이 상당히 많아졌다..
그냥 완전 탐색을 했으면 코드가 더 깔끔했을듯 하다.

profile
덕업일치 iOS 개발자

0개의 댓글