문제 상황
다음과 같은 숫자 배열이 있다고 가정해 보겠습니다.
const arr = [1, 2, 1, 3, 2];
우리가 작성해야 할 JavaScript 함수는 이 배열을 첫 번째 인수로 받습니다. 두 번째 인수는 원하는 합계(sum)를 나타내는 숫자이며, 세 번째이자 마지막 인수는 배열에서 요소를 중복 사용하지 않고 더했을 때 원하는 합계가 되어야 하는 요소의 개수(num)를 나타내는 숫자입니다.
함수는 최종적으로 원하는 합계와 길이 조건을 모두 충족하는 그룹의 총 개수를 반환해야 합니다.
입력 및 출력 예시
입력값이 다음과 같다면,
const arr = [1, 2, 1, 3, 2]; const sum = 3; const num = 2;
출력은 다음과 같아야 합니다.
const output = 2;
그 이유는 합이 3이 되면서 길이가 2인 연속된 그룹이 정확히 두 개, 즉 [1, 2]와 [2, 1]가 존재하기 때문입니다.
구현 코드
const arr = [1, 2, 1, 3, 2];
const sum = 3;
const num = 2;
const findGroups = (arr = [], sum = 1, num = 1) => {
let count = 0;
for(let i = 0; i < arr.length; i++){
// 길이가 num인 연속된 부분 배열(슬라이딩 윈도우) 추출
const part = arr.slice(i, num + i);
const partSum = part.reduce((acc, val) => acc + val);
if(partSum === sum){
count++;
};
};
return count;
};
console.log(findGroups(arr, sum, num));코드 동작 원리
- 카운터 초기화: 조건을 만족하는 그룹의 개수를 저장하기 위해 count 변수를 0으로 초기화합니다.
- 순회 시작: for 루프를 통해 배열의 각 인덱스를 그룹의 시작점으로 삼습니다.
- 슬라이딩 윈도우: slice(i, num + i)로 현재 위치에서 길이가 num인 연속된 부분 배열을 추출합니다. 이렇게 하면 한 칸씩 이동하면서 모든 그룹을 검사할 수 있습니다.
- 합계 비교: reduce() 메서드로 해당 부분 배열의 합계를 계산한 뒤, 목표값 sum과 일치하면 count를 1 증가시킵니다.
- 결과 반환: 모든 인덱스를 검사한 후 count 값을 반환합니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
2
참고: 위 코드는 배열에서 연속된 요소들만 검사하는 슬라이딩 윈도우 방식입니다. 만약 요소의 순서나 위치에 상관없이 배열의 모든 조합(combination)을 검사하고 싶다면 재귀 호출이나 백트래킹(backtracking) 기법을 활용해야 합니다.