40일차 TIL : 프로그래머스

변시윤·2022년 12월 9일
0

내일배움캠프 4기

목록 보기
41/131

학습내용

프로그래머스
겹치는 선분의 길이


겹치는 선분의 길이

문제 설명
선분 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

입출력 예

linesresult
[[0, 1], [2, 5], [3, 9]]2
[[-1, 1], [1, 3], [3, 9]]0
[[0, 5], [3, 9], [1, 10]]8

📌 프로그래머스 풀이 참조

function solution(lines) {
  const visited = lines.reduce((a, [x, y]) => {
    for (let i = Math.min(x, y) + 1; i <= Math.max(x, y); i++) {
      a[i] = a[i] ? a[i] + 1 : 1;
    return a;
  }, {});
  return Object.values(visited).filter((v) => v > 1).length;
}

1. reduce() 메서드

  • 누적값: a
  • 현재값: lines의 요소들을 [x,y]로 지정

2. for문 - 배열의 범위

lines = [0, 2], [1, 3]이라고 가정했을 때 제일 끝에 위치한 선분의 시작점과 종료점 좌표가 각각 03이므로 반복문을 돌리는 배열의 범위 역시 이 부분이 되어야 한다. 단, 입출력 첫 번째 예제처럼 배열의 범위가 0~9여도 [1,2]에는 해당되는 선분이 없기 때문에 이 부분은 반복에서 예외된다.

  • Math.min(x, y) + 1 선분의 시작점
    [0, 2]에 포함되는 숫자는 0,1,2로 총 3개지만 선분은 두 칸에 해당된다. 즉, 반복문은 세 번이 아닌 두 번만 돌려야하므로 최소값에 1을 더한다.
  • Math.max(x, y) 선분의 종료점

    Math.min()/max()
    인자로 들어오는 숫자 집합 중 최소값/최대값을 반환하는 함수

console.log(i) 실행시 1,2,2,3을 반환한다. 2를 두 번이나 반환하는 이유는 배열 안의 배열을 돌고 있기 때문이다. 즉, [0,2]차례일 때는 1-2의 순서로 for문을 돌고[1,3] 차례가 되면 다시 2로 돌아가게 되는 것이다.

다시 말하면 첫 번째 배열이 끝나고 그 다음 배열을 돌 때, 이미 한 번 돌았던 부분을 또 돌게 될 수도 있다는 뜻이다. 즉, 그 부분이 중복되는 부분이다.

3. a[i] 값 - 중복 영역 찾기

for문을 돌 때마다 해당 인덱스의 a값을 a 객체에 반환한다. 이때 삼항연산자로 a[i]가 존재한다면 a[i]의 value에 1을 더하고 존재하지 않을시엔 무조건 1을 반환한다.

선분의 좌표가 중복되지 않을 경우 a[i]의 key/value가 존재하지 않기 때문이다. 즉, 중복되는 선분은 무조건 2이상을 반환한다.

이렇게 반환한 a[i]의 값들은 a 객체에 최종적으로 { a[i] : a[i] ? a[i] + 1 : 1 } 형태로 들어간다.

풀이
1. [0, 2]0 차례

  • a 객체: {}
  • i : 1
  • a[i] = a["1"] ? a["1"] + 1 : 1; => 1

    return 뒤에 있는 {중괄호} 다음은 초기값에 해당된다. 초기값이 빈 객체 {}이므로 a 역시 {}가 된다. 즉, a에 아무런 값도 없기 때문에 a["1"]null에 해당되므로 삼항연산자에 의해 1을 반환

    a[1] = 1 ➡️ a 객체로 삽입

  1. [0, 2]2 차례
  • a 객체 : a = { '1': 1 }
  • i : 2
  • a[2] = a["2"] ? a["2"] + 1 : 1; => 1

    1번과 마찬가지로 a객체에 ["2"]에 해당하는 key가 없으므로 1을 반환

    a[2] = 1

  1. return a[1, 3]1 차례
  • a 객체 : { '1': 1, '2': 1 }
  • i : 2
  • a[2] = a["2"] ? a["2"] + 1 : 1; => 2

    a 객체에 a["2"]에 해당하는 key/value가 있는 상태이므로 a["2"]의 value에 1을 더해서 2를 반환

    a[2] = 2로 변경

  1. [1, 3]3 차례
  • a 객체 : { '1': 1, '2': 2 }
  • i : 3
  • a[3] = a["3"] ? a["3"] + 1 : 1; => 1

    a 객체에 ["3"]에 해당하는 key가 없으므로 1을 반환

    a[3] = 1

  1. 최종 a 객체 반환
    const visited = { '1': 1, '2': 2, '3': 1 }

4. filter() - 중복 영역 반환하기

  • visited의 value만을 추출해 배열로 생성
  • filter() 메서드로 배열의 요소들 중 1보다 큰 요소의 길이를 반환

Object.keys()/values()
객체의 key/value만을 반환하는 함수



특강을 제외하면 오늘 하루종일 이것만 공부했다..... 내 힘으로 풀어보다가 안 풀려서 다른 사람의 풀이를 참조했는데 그것조차도 이해가 안가는 것이다....ㅜㅜ 푸는 것도 못했는데 풀이조차 이해 못하는 건 스스로 용납이 안돼서 이것만 줄창 풀이하다가 오늘 하루를 다썼다...

나는 잘만든 영화 볼 때 빼고는 우는 일이 거의 없는데 오늘 이 문제를 풀다가 울었다. 사람이 극한으로 짜증나면 울 수도 있다는 걸 오늘 처음 알았다. 그래서 기분이 계속 안좋았었는데 특강 때 튜터님께서 훌륭한 개발자의 자질은 어떤 문제를 해결하기 위해 집념을 갖고 고민하고 괴로워하는 것이라고 말씀해주셔서 위로가 되었다. 비록 직접 풀지는 못했지만 이해하기 위해서 오늘 하루종일 무진장 괴로웠었고 결국에는 이해했으니까 한 단계 성장했다고 믿는다. 비록... 원래 듣기로 예정되어 있었던 리덕스 파트는 시작도 못했지만 말이다 ㅎ..... 주말에 들어야지 뭐.. 이번 주말도 영화 예매 취소다..

profile
개그우먼(개발을 그은성으로 하는 우먼)

0개의 댓글