방의 개수

유성재·2023년 1월 2일
0
post-custom-banner

문제

풀이

꽤 어려웠던 문제고 푼 지금도 몇가지 아쉬움이 남아있는 문제다

먼저 이 문제를 풀기 위해서는 어떤 조건에서 방이 완성되는 것으로 취급되는지를 알아야한다.

방이 완성되는 조건은 두가지다

1.방문한 지점을 한번 더 방문했을 때, 처음 지나온 길이라면 방이 하나 완성된다.

2.두 대각선이 교차될 경우 방이 하나 완성된다.

나는 이 두 조건중 두번째를 너무 늦게 깨달아서 상당히 헤맸는데, 사실 직접 몇가지 테스트 케이스를 그리면서 생각해보면 금방 눈치챌 수 있다.

내가 푼 방법은 다음과 같다.

1.new Map()을 하나 선언하고 좌표를 key값으로, 그 좌표 기준으로 어떤 직선들이 그려졌는지를 담은 Set을 value로 하여 값을 기록한다.

2.값을 기록할 때, 방이 완성되는 조건이 달성된다면 answer++를 해준다.

코드는 다음과 같다.

function solution(arrows) {
    var answer = 0;
    var map = new Map();
    var point = [0,0]
    var end = [point[0],point[1]]
    
    for(var idx in arrows){

        //현재 지점이 기록되어있지 않다면 map에 등록
        if(!map.has(point[0]+"|"+point[1])){
            map.set(point[0]+"|"+point[1],new Set());
        }
        
        //만약 이 직선이 처음 나온 직선이라면
        if(!map.get(point[0]+"|"+point[1]).has(arrows[idx])){
            //map의 현재 지점에 현재 직선 추가
            map.get(point[0]+"|"+point[1]).add(arrows[idx])
            //대각선의 경우 교차가 발생했는지 확인하고 발생했을 경우 카운트++
            if(arrows[idx] == 1 || arrows[idx] == 3 ){
                if(map.has(point[0]+1+"|"+point[1])){
                    if(map.get(point[0]+1+"|"+point[1]).has(8-arrows[idx])){
                        answer++
                    }
                }
            }else if(arrows[idx] == 5 || arrows[idx] == 7){
                if(map.has(point[0]-1+"|"+point[1])){
                    if(map.get(point[0]-1+"|"+point[1]).has(8-arrows[idx])){
                        answer++

                    }
                }
            }
        }
        
        //직선 방향에 따라 현재 지점을 이동
        switch(arrows[idx]){
            case 0:
                point = [point[0],point[1]+1]
                break;
            case 1:
                point = [point[0]+1,point[1]+1]
                break;
            case 2:
                point = [point[0]+1,point[1]]
                break;
            case 3:
                point = [point[0]+1,point[1]-1]
                break;
            case 4:
                point = [point[0],point[1]-1]
                break;
            case 5:
                point = [point[0]-1,point[1]-1]
                break;
            case 6:
                point = [point[0]-1,+point[1]]
                break;
            case 7:
                point = [point[0]-1,point[1]+1]
                break;   
        }
        
        //이동한 지점이 처음 방문한 지역일 경우 map에 등록
        if(!map.has(point[0]+"|"+point[1])){
            map.set(point[0]+"|"+point[1],new Set());
        }else{//처음 방문한 지역이 아닐 경우
            //새로운 직선인지 확인하고 새로운 직선이라면 카운트++
            if(!map.get(point[0]+"|"+point[1]).has(arrows[idx]>=4 ? (arrows[idx]-4) : (arrows[idx]+4))){
                answer++
            }
        }
        //현재 지점에 이번에 지나온 직선 기록
        arrows[idx]>=4 ? map.get(point[0]+"|"+point[1]).add(arrows[idx]-4) : map.get(point[0]+"|"+point[1]).add(arrows[idx]+4)

    }
    
    return answer;
}

풀이 자체는 설명한 그대로다.

대신 내 코드에서 아쉬운 부분이 있는데 원래 목표는 [0,0]과 같은 좌표를 담은 배열을 key값으로 하여 Map을 구성하는 것이었는데

point = [0,0]과 end = [point[0],point[1]]이 다른 판정이라 기록하는 과정에서 제대로 되지 않아 임의로 key값을 point[0] + "|" + point[1]의 방식으로 구현한 점이 상당히 아쉬운 부분이다.

이 부분에 대해서는 왜 안되는지, 그리고 어떻게 해야 해결할 수 있는지 조사해서 추후 추가하려 한다.

추가

왜 key값이 내가 원한대로 세팅되지 않았었는지에 대한 공부를 했다. 관련 내용을 정리한 페이지를 만들었으니 링크를 남겨둔다.
https://velog.io/@yoosj97/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9B%90%EC%8B%9C-%EC%9E%90%EB%A3%8C%ED%98%95-%EB%B3%80%EC%88%98%EC%99%80-%EC%B0%B8%EC%A1%B0-%EC%9E%90%EB%A3%8C%ED%98%95-%EB%B3%80%EC%88%98

profile
열정 있는 개발자
post-custom-banner

0개의 댓글