본문 바로가기

프로그래머스 0단계 - 겹치는 선분의 길이 본문

알고리즘/0단계

프로그래머스 0단계 - 겹치는 선분의 길이

개발자로 거듭나기 2023. 6. 4. 17:23
반응형

0 단계 : 겹치는 선분의 길이

코딩테스트 연습 > 코딩테스트 입문 > 겹치는 선분의 길이


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

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

line_2.png

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


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

입출력 예
lines result
[[0, 1], [2, 5], [3, 9]] 2
[[-1, 1], [1, 3], [3, 9]] 0
[[0, 5], [3, 9], [1, 10]] 8

입출력 예 설명

입출력 예 #1

  • 두 번째, 세 번째 선분 [2, 5], [3, 9]가 [3, 5] 구간에 겹쳐있으므로 2를 return 합니다.


입출력 예 #2

  • 겹친 선분이 없으므로 0을 return 합니다.


입출력 예 #3

  • 첫 번째와 두 번째 선분이 [3, 5] 구간에서 겹칩니다.
  • 첫 번째와 세 번째 선분 [1, 5] 구간에서 겹칩니다.
  • 두 번째와 세 번째 선분 [3, 9] 구간에서 겹칩니다.
  • 따라서 [1, 9] 구간에 두 개 이상의 선분이 겹쳐있으므로, 8을 return 합니다.

코드

function solution(lines) {
    // 1. 구간구하기
    // [0,5]의 구간은 [0,1], [1,2], [2,3], [3,4], [4,5] 의 구간이 있죠? 그걸 구해줍니다.
    const calFullRange = (range) => Array.from({length : range[1] - range[0]}, (_, index) => [index + range[0], index + range[0] + 1]);
    
    const firstRange = calFullRange(lines[0]);
    const secondRange = calFullRange(lines[1]);
    const thirdRange = calFullRange(lines[2]);
    
    // 2. 1,2 2,3 1,3 겹치는 집합만들기
    // 아까 구했던 [0,1], [1,2], [2,3], [3,4], [4,5] 와 같은 구간을 이용해서
    // 1번째 선분과 2번째선분, 2번째 선분과 3번째 선분, 1번째 선분과 3번째 선분에 각각 겹치는 구간을 구해줍니다.
    // [0, 5], [3, 9]의 겹치는 구간은 [3,4], [4,5] 입니다.
    const intersection = (range1, range2) => {
        const range1Mapped = range1.map(item => JSON.stringify(item));
        const range2Mapped = range2.map(item => JSON.stringify(item));
        
        return range1Mapped.filter(item => range2Mapped.includes(item)).map(str => JSON.parse(str));
    }
    
    const oneTwo = intersection(firstRange, secondRange);
    const twoThree = intersection(secondRange, thirdRange);
    const oneThree = intersection(firstRange, thirdRange);
    
    // 3. 최종적으로 합집합을 구해서 return;
    // 세집합의 합집합은 모든 구간을 합치고, 교집합(겹치는 부분)을 없애면 총 길이가 나옵니다.
    const union = [...oneTwo, ...twoThree, ...oneThree].map(item => JSON.stringify(item));
    return [...new Set(union)].length;
}

리뷰

1. 3단계로 나눌 수 있습니다.
2. 첫번째로, line1,2,3의 각각의 구간을 구해줍니다.
3. 두번째로, line1 && line2, line2 && line3, line1 && line3 각각의 겹치는 선분구간을 구해줍니다.
4. 세번째로, 배열 하나에 전부 넣고, 중복을 제거하면 온전한 선분 두개이상이 겹치는 구간을 구할 수 있고, 그것의 길이를 return 해줍니다.

총평 : 두배열이 서로 같은배열인지 비교할 때 JSON.stringify를 사용하는게 살짝 깔끔하지 못한 것 같습니다.


출처 : https://school.programmers.co.kr/learn/courses/30/lessons/120876
반응형
Comments