학습내용
프로그래머스
겹치는 선분의 길이
문제 설명
선분 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입출력 예
lines result [[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;
}
reduce()
메서드a
lines
의 요소들을 [x,y]
로 지정for
문 - 배열의 범위lines
= [0, 2]
, [1, 3]
이라고 가정했을 때 제일 끝에 위치한 선분의 시작점과 종료점 좌표가 각각 0
과 3
이므로 반복문을 돌리는 배열의 범위 역시 이 부분이 되어야 한다. 단, 입출력 첫 번째 예제처럼 배열의 범위가 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
로 돌아가게 되는 것이다.
다시 말하면 첫 번째 배열이 끝나고 그 다음 배열을 돌 때, 이미 한 번 돌았던 부분을 또 돌게 될 수도 있다는 뜻이다. 즉, 그 부분이 중복되는 부분이다.
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
: 1a[i] = a["1"] ? a["1"] + 1 : 1;
=> 1
return
뒤에 있는{중괄호}
다음은 초기값에 해당된다. 초기값이 빈 객체{}
이므로a
역시{}
가 된다. 즉,a
에 아무런 값도 없기 때문에a["1"]
은null
에 해당되므로 삼항연산자에 의해1
을 반환
a[1]
=1
➡️a
객체로 삽입
[0, 2]
의 2
차례 a
객체 : a = { '1': 1 }
i
: 2a[2] = a["2"] ? a["2"] + 1 : 1;
=> 11번과 마찬가지로
a
객체에["2"]
에 해당하는 key가 없으므로1
을 반환
a[2]
=1
return a
후 [1, 3]
의 1
차례a
객체 : { '1': 1, '2': 1 }
i
: 2a[2] = a["2"] ? a["2"] + 1 : 1;
=> 2
a
객체에a["2"]
에 해당하는 key/value가 있는 상태이므로a["2"]
의 value에 1을 더해서2
를 반환
a[2]
=2
로 변경
[1, 3]
의 3
차례a
객체 : { '1': 1, '2': 2 }
i
: 3a[3] = a["3"] ? a["3"] + 1 : 1;
=> 1
a
객체에["3"]
에 해당하는 key가 없으므로1
을 반환
a[3]
=1
a
객체 반환const visited = { '1': 1, '2': 2, '3': 1 }
visited
의 value만을 추출해 배열로 생성filter()
메서드로 배열의 요소들 중 1보다 큰 요소의 길이를 반환
Object.keys()
/values()
객체의 key/value만을 반환하는 함수
특강을 제외하면 오늘 하루종일 이것만 공부했다..... 내 힘으로 풀어보다가 안 풀려서 다른 사람의 풀이를 참조했는데 그것조차도 이해가 안가는 것이다....ㅜㅜ 푸는 것도 못했는데 풀이조차 이해 못하는 건 스스로 용납이 안돼서 이것만 줄창 풀이하다가 오늘 하루를 다썼다...
나는 잘만든 영화 볼 때 빼고는 우는 일이 거의 없는데 오늘 이 문제를 풀다가 울었다. 사람이 극한으로 짜증나면 울 수도 있다는 걸 오늘 처음 알았다. 그래서 기분이 계속 안좋았었는데 특강 때 튜터님께서 훌륭한 개발자의 자질은 어떤 문제를 해결하기 위해 집념을 갖고 고민하고 괴로워하는 것이라고 말씀해주셔서 위로가 되었다. 비록 직접 풀지는 못했지만 이해하기 위해서 오늘 하루종일 무진장 괴로웠었고 결국에는 이해했으니까 한 단계 성장했다고 믿는다. 비록... 원래 듣기로 예정되어 있었던 리덕스 파트는 시작도 못했지만 말이다 ㅎ..... 주말에 들어야지 뭐.. 이번 주말도 영화 예매 취소다..