ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스 / JS] LV.0 겹치는 선분의 길이
    Algorithm/프로그래머스 2022. 12. 12. 18:36
    반응형

    문제 설명

    선분 3개가 평행하게 놓여 있습니다. 세 선분의 시작과 끝 좌표가 [[start, end], [start, end], [start, end]] 형태로 들어있는 2차원 배열 lines가 매개변수로 주어질 때, 두 개 이상의 선분이 겹치는 부분의 길이를 return 하도록 solution 함수를 완성해보세요.

    lines가 [[0, 2], [-3, -1], [-2, 1]]일 때 그림으로 나타내면 다음과 같습니다.

     

    예시 이미지

     

     

    선분이 두 개 이상 겹친 곳은 [-2, -1], [0, 1]로 길이 2만큼 겹쳐있습니다.


    제한사항

    • lines의 길이 = 3
    • lines의 원소의 길이 = 2
    • 모든 선분은 길이가 1 이상입니다.
    • lines의 원소는 [a, b] 형태이며, a, b는 각각 선분의 양 끝점 입니다.
    • -100 ≤ a < b ≤ 100

    풀이

    function solution(lines) {
        let dict = {};
        let arrBefore = '';
        let totalLength = 0;
        let flag = false;
    
        lines.forEach((ele, idx) => {
            for (let value = ele[0]; value <= ele[1]; value++){
                if (dict[value]) {
                    dict[value][idx]++;
    
                } else {
                    dict[value] = [0, 0, 0];
                    dict[value][idx]++;
                }
            }
        })
    	//object의 특정한 순서를 가지며 정렬되지 않기 때문에 key값을 정렬해 이용한다.
        let sortedKeys = Object.keys(dict).sort((a,b) => Number(a)-Number(b))
    
        for (let key of sortedKeys){
            let numOfOne = dict[key].filter(ele => ele === 1).length;
            let arrCurr = dict[key].join('');
    
            if ((numOfOne > 1)) {
                if((arrBefore === arrCurr) || (arrBefore === '111') || ((arrCurr === '111') && (flag === true))) {
                    totalLength++;  
                } 
                flag = true;
            } else {
                flag = false;
            }
            arrBefore = arrCurr;
        }
    
        return totalLength;
    }

     

     

    사고과정

    1. lines에 선분의 양 끝의 위치가 주어지므로 각 좌표가 선분에 포함되는 여부를 데이터화 하여 저장하자
    2. "key = value"를 "좌표 = 지나가는 선분의 수" 로 저장하기 위해 obj 자료형을 사용하는게 편하겠다.
    3. 단순히 각 좌표를 지나가는 선분의 수에 대한 데이터만으론 [0, 2], [2, 3], [3, 5] 와 같은 경우 틀린값이 발생하네?
    4. lines의 idx로 각 선분을 특정할 수 있고 obj 자료형으로 데이터를 저장했으니 value에 길이가 3인 arr를 저장해 사용하면 단순히 지나간 선분의 수가 아닌 어떤 선분이 지나갔는지도 특정할 수 있겠다.
    5. 현재 좌표에서 선분이 두개 이상 지나가는 조건 하에 (1 )전 좌표의 데이터와 현재 좌표가 같은 경우, (2) 전 좌표에 선분이 3개가 지나가는 경우 겹치는 부분의 길이가 1씩 늘어나게 하면되겠다.
    6. 앞서 조건만으론 모든 경우를 포함하지 못하네, 전 좌표에 선분이 2개 지나가고 현재 좌표에 선분이 3개 지나가는 경우를 위해 flag 변수를 추가하자( arrBefore도 사용 가능하지만 split, filter 적용하는 것 보단 변수하나 추가하는게 효율적일 것 같다)

     

    평가

      다른 사람들의 코드를 보니 [a, b)의 범위 (2)의 논리 구조를 적용하면 (3), (6)과 같은 종류의 오류가 발생하지 않는다. 즉, 주어진 데이터를 적절히 활용하지 못해 불필요한 연산이 추가되었고 코드 효율성이 떨어지는 결과를 낳았다.

    ...
    
    lines.forEach(([a, b]) => {
    	for(; a < b; a++) line[a+100]++;
    });
    
        return line.reduce((a, c) =>  c > 1 ? a + 1 : a, 0)
    }

     

     

    개선점

    1. 데이터 이용 범위 변경 -> 복잡한 조건식이 불필요해지고 단순 데이터 확인만 필요해짐
    2. 자료형 obj -> arr로 변경을 통한 sort함수 생략

     

    알게된점

     

     

    반응형

    댓글

Designed by Tistory.