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개의 댓글

관련 채용 정보