문제
TRY
const clothes1 = [
['yellowhat', 'headgear'],
['bluesunglasses', 'eyewear'],
['green_turban', 'headgear'],
];
const clothes2 = [
['crowmask', 'face'],
['bluesunglasses', 'face'],
['smoky_makeup', 'face'],
];
function solution(clothes) {
// 옷의 종류와 종류별 갯수를 저장 할 객체
let obj = {};
for (let i = 0; i < clothes.length; i++) {
// 옷의 종류가 정의 되지 않았으면 옷의 종류의 value = 1
if (obj[clothes[i][1]] === undefined) {
obj[clothes[i][1]] = 1;
// 종류가 존재하면 value에 + 1
} else {
obj[clothes[i][1]]++;
}
}
// 옷의 종류별 개수를 담을 배열을 초기화
let clothesKind = [];
// 옷의 종류별 갯수를 clotherKind 배열에 담아준다.
for (const key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
clothesKind.push(obj[key]);
}
}
// 경우의 수를 담을 result 변수 초기화
let result = 0;
//
for (let i = 0; i < clothesKind.length; i++) {
// ex) [1,2]
// 첫 번째 경우의 수(1) + 두 번째 경우의 수(2) + 둘의 곱(2) = 5
// ex) [1,2,3]
// 이전 경우의 수(5) + 자신의 경우의 수(3) + 둘의 곱(5*3) = 23
// i가 0 이상 일때
if (i) {
result += result * clothesKind[i];
}
result += clothesKind[i];
}
return result;
}
console.log(solution(clothes1));
console.log(solution(clothes2));
객체를 만들고 옷의 종류별 개수를 파악하는 건 쉬웠는데 옷을 조합하는 경우의 수를 알아차리는 게 힘들었다.
처음에는 옷의 종류가 [1,2,3] 가지 있다고 하면 1*2*3 = 6인 줄 알았는데
이건 3가지 옷을 전부 입어야 할 때의 경우의 수 이고
문제는 1가지 종류만 입을 수도 있고 2가지 종류만 입을 수도 있다.
그래서 처음 내가 생각한 경우의 수 방식은 (이전 경우의 수 + 자신의 경우의 수 + 둘의 곱) 방식이었다.
[1,2,3] 경우를 예를 들면
[1] 일때 경우의 수 = 1
[1,2] 일때 경우의 수 = 이전 경우의 수(1) + 자신의 경우의수(2) + 둘의 곱(1*2) => 5
[1,2,3] 일 때 경우의 수 = 이전 경우의 수(5) + 자신의 경우의 수(3) + 둘의 곱(5*3) => 23
이런 방식으로 답을 구했다.
Refactoring
const clothes1 = [
['yellowhat', 'headgear'],
['bluesunglasses', 'eyewear'],
['green_turban', 'headgear'],
];
const clothes2 = [
['crowmask', 'face'],
['bluesunglasses', 'face'],
['smoky_makeup', 'face'],
];
function solution(clothes) {
let obj = {};
for (let i = 0; i < clothes.length; i++) {
obj[clothes[i][1]] = (obj[clothes[i][1]] || 1) + 1;
}
let result = 1;
for (const key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
result *= obj[key];
}
}
return result - 1;
}
console.log(solution(clothes1));
console.log(solution(clothes2));
다른 풀이를 보다가 알게 된 훨씬 쉬운 방식이
(자신의 경우의 수 + 1) 로 다 곱해주고 -1(옷을 한 가지도 안 입을 경우) 이다.
다시 [1,2,3] 으로 예를 들면
1 X = > 2(자신의 경우의 수(1) + 안 입는 경우의 수(1)
1 1 X = > 3(자신의 경우의 수(2) + 안 입는 경우의 수(1)
1 1 1 X = > 4(자신의 경우의 수(4) + 안 입는 경우의 수(1)
를 다 곱한 24에서 XXX(모두 다 안 입는 경우) 인 경우 1만 빼주면 되는 것이다.
또 유용하게 알게 된 부분이
옷을 객체에 넣어주는 부분에서 사용하게 된 Logical OR(||) 이다.
합집합으로만 사용하는 줄 알았던 || 연산자가 이렇게 간편하게 사용할 수 있구나 라는 걸 새삼 느꼈다.
&&와 ||의 단축평가에 대해서는 아래 분이 정말 자세하게 설명을 해주셔서 쉽게 이해할 수 있었다.
Refactoring
const clothes1 = [
['yellowhat', 'headgear'],
['bluesunglasses', 'eyewear'],
['green_turban', 'headgear'],
];
const clothes2 = [
['crowmask', 'face'],
['bluesunglasses', 'face'],
['smoky_makeup', 'face'],
];
function solution(clothes) {
return (
Object.values(
clothes.reduce((obj, t) => {
obj[t[1]] = (obj[t[1]] || 1) + 1;
return obj;
}, {}),
).reduce((a, b) => a * b, 1) - 1
);
}
console.log(solution(clothes1));
console.log(solution(clothes2));
두 번째 방식을 극도로 축약해서 return 한방에 보내버린다.
Array.reduce() 를 이용하여 옷의 경우의 수를 종류별 개수 배열로 반환하고 그 배열을 다시 reduce하여 경우의 수를 구한 뒤
바로 return 해버리는 방식이다.
'ALGORITHM > 프로그래머스 With JS' 카테고리의 다른 글
[프로그래머스] 기능개발 / Javascript (0) | 2021.04.30 |
---|---|
[프로그래머스] 다리를 지나는 트럭 / Javascript (0) | 2021.04.29 |
[프로그래머스] 체육복 / Javascript (2) | 2021.04.28 |
[프로그래머스] 모의고사 / Javascript (0) | 2021.04.28 |
[프로그래머스] K번째수 / Javascript (0) | 2021.04.27 |
댓글