개발조각

[프로그래머스] 방문 길이 본문

알고리즘🅰/프로그래머스

[프로그래머스] 방문 길이

개발조각 2022. 5. 4. 23:04
728x90
반응형

이번 문제는 쉽게 풀릴 것 같은데 안 풀려서 질문하기 SOS를 받아 풀었습니다.


접근방법

이 문제는 캐릭터가 처음 걸어본 길의 길을 구하는 문제입니다.

그리고 문제 설명에 좌표평면의 경계를 넘어가는 명령어는 무시한다는 조건이 있습니다.

 

위에 있는 예제만 따져서 문제를 푼다면 쉽지만

만약 "UDU"일 경우 return값이 1인 경우도 생각해봐야 됩니다.

 

그래서 생각한 방법은 시작 지점, 도착지점을 다 구하는 방식으로 구하였습니다.

 

 

예를 들어, "ULURRDLLU"로 명령했다면

시작 위치, 도착 위치 -> 시작x, 시작y, 도착x, 도착y

  1. 0,0,0,1
  2. 0,1,-1,1
  3. -1,1,-1,2
  4. -1,2,0,2
  5. 0,2,1,2
  6. 1,2,1,1
  7. 1,1,0,1
  8. 0,1,-1,1
  9. -1,1,-1,2

시작 위치, 도착 위치가 같은 것은 제거해주면 됩니다.

그럼 7이 됩니다.

 

 

그러나 "UDU"로 명령했다면 조금 다르게 생각을 해봐야 됩니다.

  1. 0,0,0,1
  2. 0,1,0,0
  3. 0,0,0,1

이렇게 보시면 0,0,0,1만 공통이니 답이 2가 될 것 같지만

그려보면 답은 1입니다.

그래서 이럴 경우를 대비해서

시작 위치,도착 위치뿐만 아니라 도착 위치,시작 위치도 체크를 했습니다.

 

시작 위치, 도착 위치 -> 도착 위치, 시작 위치

  1. 0,0,0,1 -> 0,1, 0,0
  2. 0,1,0,0 -> 0,0, 0,1
  3. 0,0,0,1 -> 0,1, 0,0

그러면 2개가 겹침으로 답이 1이 됩니다.


해결방안

function solution(dirs) {
    var answer = 0;   
    let [x, y] = [0, 0];
    let [X, Y] = [0, 0];
    let move = [];
    for(let i=0; i<dirs.length; i++){
        if(dirs[i] === 'U'){
            if(y===5) continue;
            Y++;
        }
        else if(dirs[i] === 'D'){
            if(y===-5) continue;
            Y--;
        }
        else if(dirs[i] === 'R'){
            if(x===5) continue;
            X++;
        }
        else if(dirs[i] === 'L'){
            if(x===-5) continue;
            X--;
        }
        
        let idxOf = move.indexOf([x, y, X, Y].join(''));
        let rvsIdxOf = move.indexOf([X, Y, x, y].join(''));
        if(idxOf === -1 && rvsIdxOf === -1) answer++;
        move.push([x, y, X, Y].join(''));
        
        x = X;
        y = Y;        
    }
    return answer;      
}
  • answer : 캐릭터가 처음 걸어본 길의 길이
  • [x, y] : 시작 위치
  • [X, Y] : 도착 위치
  • move : "시작 위치+도착 위치"를 담아둘 배열

 

해결방안 순서

  1. dirs[i]가 "U", "D", "R", "L"에 따라 도착 위치 이동시키기
  2. 시작 위치 도착 위치, 도착 위치 시작 위치가 move배열에 없으면 answer++해주기
  3. 시작 위치도착위치 move배열에 담기
  4. 시작위치 바꿔주기

 

1단계. dirs[i]가 "U", "D", "R", "L"에 따라 도착 위치 이동시키기

if(dirs[i] === 'U'){
    if(y===5) continue;
    Y++;
}
else if(dirs[i] === 'D'){
    if(y===-5) continue;
    Y--;
}
else if(dirs[i] === 'R'){
    if(x===5) continue;
    X++;
}
else if(dirs[i] === 'L'){
    if(x===-5) continue;
    X--;
}

dirs[i]가 "U", "D", "R", "L"에 따라 도착 위치 이동시켜주었습니다.

이때 "좌표평면의 경계를 넘어가는 명령어는 무시합니다."라는 조건을 해결하기 위해

if(x===5) continue;를 넣어주어 경계를 넘어가면 다음 for문으로 넘겼습니다.

 

2단계. 시작 위치 도착 위치, 도착 위치 시작 위치가 move배열에 없으면 answer++해주기

let idxOf = move.indexOf([x, y, X, Y].join(''));
let rvsIdxOf = move.indexOf([X, Y, x, y].join(''));
if(idxOf === -1 && rvsIdxOf === -1) answer++;
  • idxOf : 현재 시작 위치 도착 위치가 move배열 안에 있는지 확인
  • rvsIdxOf : 현재 도착 위치 시작 위치가 move배열 안에 있는지 확인

둘 다 없을 경우(-1) answer++ 해주었습니다.

move배열에 있는지 확인하기 위해 indexOf를 이용해서 찾아주었습니다.

 

3단계. 시작 위치 도착 위치 move배열에 담기

move.push([x, y, X, Y].join(''));

 

4단계. 시작 위치 바꿔주기

x = X;
y = Y;

여기까지 프로그래머스 방문 길이 해결방안에 대해 설명해보았습니다.

728x90
반응형
Comments