Skip to content

Latest commit

 

History

History
107 lines (102 loc) · 4.49 KB

프로그래머스(조이스틱).md

File metadata and controls

107 lines (102 loc) · 4.49 KB

function solution(name) {
    const distance = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    let _len = name.length
    let ans = 0
    let location = 0
    let visited = new Array(_len).fill(0)
    //이미 'A'인 곳은 방문할 필요가 없다.
    for (let i = 0; i < _len; i++) {
        if (name[i] == 'A')
            visited[i] = 1
    }
    while (1) {
        let flag = 0
        //문자열을 전부 방문했는지 확인하고 값을 반환
        for (let i = 0; i < _len; i++) {
            if (!visited[i])
                flag = 1
        }
        if (!flag) return ans
        //지금 location에 아직 방문하지 않았을 경우 바로 방문하면 됨
        if (!visited[location]) {
            ans += distance[Math.abs('A'.charCodeAt() - name[location].charCodeAt())]
            visited[location] = 1
        }
        //지금 location에 방문한 경우 다음으로 방문할 location을 찾아야 한다.
        else {
            let right = 0
            let left = 0
            //location을 기준으로 오른쪽에 방문하지 않은 가장 가까운 곳이 얼마나 멀리 떨어져있는지 확인
            for (let i = 1; i < _len; i++) {
                //문자열의 맨 마지막을 넘지 않는 경우
                if (location + i < _len) {
                    if (!visited[location + i]) {
                        right = i
                        break
                    }
                //문자열의 맨 마지막을 넘는 경우이기 때문에 다시 맨 앞으로 돌아와야 한다.
                } else {
                    if (!visited[location + i - _len]) {
                        right = i
                        break
                    }
                }
            }
            //location을 기준으로 왼쪽에 방문하지 않은 가장 가까운 곳이 얼마나 멀리 떨어져있는지 확인
            for (let i = 1; i < _len; i++) {
                //문자열의 맨 처음을 넘어가지 않는 경우
                if (location - i >= 0) {
                    if (!visited[location - i]) {
                        left = i
                        break
                    }
                //문자열의 맨 처음을 넘는 경우 다시 맨 뒤로 돌아가야 한다.
                } else {
                    if (!visited[location - i + _len]) {
                        left = i
                        break
                    }
                }
            }
            //오른쪽이 더 가깝거나 같은 경우
            if (right <= left) {
                if (location + right < _len) {
                    location += right
                    console.log(location)
                    ans += distance[Math.abs('A'.charCodeAt() - name[location].charCodeAt())]
                    ans += right
                    visited[location] = 1
                }else{
                    location = location + right - _len
                    console.log(location)
                    ans += distance[Math.abs('A'.charCodeAt() - name[location].charCodeAt())]
                    ans += right
                    visited[location] = 1
                }
            }
            //왼쪽이 더 가까운 경우
            else {
                if (location - left >= 0) {
                    location -= left
                    console.log(location)
                    ans += distance[Math.abs('A'.charCodeAt() - name[location].charCodeAt())]
                    ans += left
                    visited[location] = 1
                } else {
                    location = location - left + _len
                    console.log(location)
                    ans += distance[Math.abs('A'.charCodeAt() - name[location].charCodeAt())]
                    ans += left
                    visited[location] = 1
                }
            }
        }
    }
}

가장 주요한 개념은 지금의 위치에서 왼쪽이 더 가까운지 오른쪽이 더 가까운지를 파악하고 더 가까운 곳으로 가면 된다. 이 판단을 계속해서 반복시키면 된다.

왼쪽과 오른쪽의 거리가 같은 경우 따로 명시되어 있지 않았었기 떄문에 그냥 아무 경우에나 넣어주면 된다 생각해서 오른쪽을 먼저 수행하게 했다. 다 풀고 질문하기를 보니 왼쪽을 먼저 수행하게 하면 틀리다고 나오나보다. 운이 굉장히 좋았다.