자기전에 진짜 쉬운거 하나 풀고 자자 싶어서 프로그래머스 LEVEL1 중에 만만한 놈을 잡아서 풀려고 했다.
https://school.programmers.co.kr/learn/courses/30/lessons/131705
간단하게 문제 설명을 하자면!
1. 그냥 배열로 숫자 줄테니까
2. 배열 요소 3개 합해서 0되는 조합 개수 출력해
이게 끝이다.
당연히 아래와 같이 for문 3개 쓰면 풀릴 것인데,, 이게 정말 좋은 풀이인가? 싶어서 모범답안을 보니 reduce를 사용하더라 , 그래서 그김에 평소 그냥 sum함수 만들때나 사용했던 reduce좀 알아보려고 한다.
직관적 3중 포문 풀이
function solution(number) { var answer = 0 for (let i = 0; i<number.length-2; i++){ for(let j= i+1; j<number.length-1;j++){ for(let k = j+1;k<number.length;k++){ if(number[i]+number[j]+number[k] ===0){ answer+=1 } } } } return answer; }
멋있는 reduce풀이 예시
function solution(number) { let result = 0; const combination = (current, start) => { if (current.length === 3) { result += current.reduce((acc, cur) => acc + cur, 0) === 0 ? 1 : 0; return; } for (let i = start; i < number.length; i++) { combination([...current, number[i]], i + 1); } } combination([], 0); return result; }
사전에서도 나오듯 줄인다는 의미를 갖고있다.
리듀스 함수는 배열의 요소를 순차적으로 순회하며 숫자든 배열이든 객체든 하나의 값으로 줄여 return 하는 함수라고 생각하시면 될 것 같다.
MDN에 나온 사례를 살펴보면 다음과같다
const array1 = [1, 2, 3, 4];
// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
(accumulator, currentValue) => accumulator + currentValue,
initialValue,
);
console.log(sumWithInitial);
// Expected output: 10
누적값,현재값을 인자로 갖고, 맨뒤 인자로 initialValue가 이제 첫 accumulator 값이 될 것이다.
그렇게 생각하고 작동 순서를 파악해보면
- initialValue(0)로 시작
- 배열의 첫 번째 요소(currentValue) -> 1이 들어갈 것이다.
- 각 단계에서 accumulator와 currentValue를 더해준다!
- accumulator(0) + currentValue(1) = 1
- accumulator(1) + currentValue(2) = 3
- accumulator(3) + currentValue(3) = 6
- accumulator(6) + currentValue(4) = 10
이제 위에서 쓰였던 reduce를 좀 살펴보면
function solution(number) {
let result = 0;
const combination = (current, start) => {
if (current.length === 3) {
result += current.reduce((acc, cur) => acc + cur, 0) === 0 ? 1 : 0;
return;
}
for (let i = start; i < number.length; i++) {
combination([...current, number[i]], i + 1);
}
}
combination([], 0);
return result;
}
if (current.length === 3)
current 배열 원소가 3개인지 확인 -> 삼총사가 모였는지 판단
current.reduce((acc, cur) => acc + cur, 0) === 0 ? 1 : 0;
: current 배열의 합이 0인지 확인
합이 0이면 result에 1을 더하고, 아니면 패스 !
그리고 밑에서 또 combination으로 재귀호출해주면서 모든 원소를 판단해주는 것이다.
이렇게 reduce를 또 하나의 조건처럼 활용하면서 점검하고 이걸또 재귀로 배열을 채워준 것을 보니까 진짜 이렇게 컴퓨터적으로 사고하고 싶다고 생각했따. 쉬운문제들에서는 풀이의 모범답안을 좀 잘 참고해서 얻어가야겠다.