ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift] 조이스틱 코딩테스트 프로그래머스
    개발/Swift 2022. 2. 13. 14:12

     

     

    문자 변환 카운팅을 위해서 아스키 코드를 활용한다.

     

    위의 아스크코드 표를 참고하면 하늘색부분을 보면 된다.

    A는 65 → Z 는 90이다.

    조이스틱을 위로 / 아래로 변경해서 원하는 문자를 찾을건데 

    위로가는 방법 , 아래로 가는 방법 두개를 비교해 최솟값을 구하면된다.

     

    찾으려는 문자의 아스키코드 번호를 알아낸 다음

    위로가는 방법은 = 아스키코드번호 - 65 (ex>A 인경우 0)

    아래는 = 91 - 아스키코드번호 이렇게 계산하면 쉽다. (Z인경우 1)

    for i in range{
            if name[i] != "A"{
                let up = name[i].asciiValue! - 65
                let down = 91 - name[i].asciiValue!
                changeCount += Int(min(up, down))
            }
        }
    

     

    더 어려웠던 문제는 이동횟수였다.

    해답에서는 이렇게 되어있었다.

    var minMove = name.count - 1
       
        for i in 0..<name.count {
           if name[i] != "A" {
               var next = i + 1
               while next<name.count && name[next] == "A" {
                   next += 1          
    					 }
               let move = 2 *  i + name.count - next
               minMove = min(move, minMove)
           }
       }
    

    봐도 모르겠어서 하나하나 대입해가면서 이해해본 결과 이 코드의 해답은 이러하다.''

    BAAABB //2번쨰 A 앞에서 돌아가기
    BABAAB  //2번쨰 A 앞에서 돌아가기  
    BBAAAB //3번쨰 A 앞에서 돌아가기
    AABABB // 오른쪽으로 세기
    ABAABB // 3번쨰 A에서 돌아가기
    
    

     

    오른쪽으로 순차적으로 움직이기 방법 + 첫번째 A앞에서 돌아가는 방법만 생각했지만

    몇번째 A에서 돌아갈지는 문자에 따라 달라진다.

    BABAAB 는 맨처음 나오는 A 에서 돌아가지만

    ABAABB 는 두번쨰 나오는 A에서 반대로 돌아가야 한다.

     

    결국 이렇게 나뉜다.

    오른쪽으로 순차적으로 움직이기

    첫번쨰 A 앞에서 돌아가기

    두번쨰 A 앞에서 돌아가기

    세번쟤.... 네번째...

    결국 다 세보고 비교해야한다.

     

    반복문을 돌린후 다음값에 A가 나오면 최솟값을 계산해낸후 기존 최솟값과 비교하여

    계속 최소값을 최신화하면서 풀이 해야한다.

    위 반복문에서 i 는 A가 발견된 직전 index 이며

    next 는 A의 위치이다. A가 연달아 나올수 있으므로 while문을 돌려 next를 +1 하면서

    연달아 나온 마지막 A값을 next에 대입했다.

    while next<name.count && name[next] == "A" {
               next += 1 
           }
    
    

    되돌아간 무빙 횟수 = A직전 index * 2(오른쪽으로 갔다가 되돌아 왔으므로) + A 이후 A아닌 문자 갯수

    이렇게 계산한후 직전 최소값과 지금 최소값을 비교해 값을 도출해 냈다.

    let move = 2 *  i + name.count - next
    minMove = min(move, minMove)
    

     

    전체 코드

     

    import Foundation
    func solution(_ name:String) -> Int {
        var ans = 0
        let name = name.map({$0})
        for i in 0..<name.count {
            if name[i] != "A" {
                let up = name[i].asciiValue! - 65
                let down = 91 - name[i].asciiValue!
                ans += Int((up<down) ? up : down)
            }
        }
    
        var minMove = name.count-1
        for i in 0..<name.count {
            if name[i] != "A" {
                var next = i + 1
                while next<name.count && name[next] == "A" {
                    next += 1
                }
                let move = 2 *  i + name.count - next
                minMove = min(move, minMove)
            }
        }
        return ans + minMove
    }
    

     

     

    댓글

Designed by Tistory.