프로그래머스 코딩테스트 연습의 해시-위장 문제
스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.
예를 들어 스파이가 가진 옷이 아래와 같고 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다.
종류 이름
얼굴 동그란 안경, 검정 선글라스
상의 파란색 티셔츠
하의 청바지
겉옷 긴 코트
스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.
clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.
같은 이름을 가진 의상은 존재하지 않습니다.
clothes의 모든 원소는 문자열로 이루어져 있습니다.
모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 ‘_’ 로만 이루어져 있습니다.
스파이는 하루에 최소 한 개의 의상은 입습니다.
clothes return
[[“yellowhat”, “headgear”], [“bluesunglasses”, “eyewear”], [“green_turban”, “headgear”]] 5
[[“crowmask”, “face”], [“bluesunglasses”, “face”], [“smoky_makeup”, “face”]] 3
reduce()를 통해 의상 타입의 중복값이 몇개인지 구했다.
해시문제 첫번째에서 배운 자료구조를 이용해보고자 그 중복값을 Map으로 만들어줬다.
의상의 타입이 모두 같은 경우는 배열의 길이를 반환했다.
그 외의 경우는 (의상1x의상2x …의상n) + (의상1x의상2 …의상n)의 식을 이용해서 총 경우의 수를 반환했다.
function solution(clothes) {
let answer;
const result = clothes.reduce((accu,curr)=> { // 1번
accu.set(curr[1], (accu.get(curr[1])||0) +1);
return accu;
},new Map()); // 2번
if(result.size === 1){ //3번
answer = clothes.length
} else {
let sum=0;
let square =1;
for (let [key, value] of result) {
sum = sum +result.get(key)
square = square*value
}
answer = sum+square
}
return answer
}
위와 같이 풀고나니 첫 2가지 테스트 케이스는 통과했지만, 실제 채점에서는 통과되지 않는 테스트 케이스가 있었다. 살펴보니 경우의 수를 구하는 식이 범용되지 않는것 같았다. 그래서 ((의상1+1)*..(의상n+1))-1로 식만 바꿔보니 통과되었다🎉
function solution(clothes) {
let answer;
const result = clothes.reduce((accu,curr)=> {
accu.set(curr[1], (accu.get(curr[1])||0) +1) ;
return accu;
},new Map());
if(result.size === 1){
answer = clothes.length
} else {
let initial=1; // ((의상1+1)*..(의상n+1))-1로 경우의 수를 구하는 식을 변경해주었다.
for (let [key, value] of result) {
initial = initial * (value+1)
answer = initial-1
}
}
return answer
}
해시 첫번째 문제에서 Map과 Set을 배웠기 때문에 써먹어봐야지! 하는 마음이 있었다. 그래서 의상의 중복값을 구할때 불필요하게 Map을 만들어준것 같았다. 그래서 initialValue에 Map을 제거하고 객체로 설정한 뒤 다시 풀어보았다.
function solution(clothes) {
let answer;
const newObject = clothes.reduce((a,b)=> {
a[b[1]] = (a[b[1]] || 0)+1;
return a
},{});
const test = Object.values(newObject)
const result = test.reduce((c,d)=>{
return c*(d+1)
},1)
return answer = result -1
}
배운점🙋🏻♀️
변수선언으로 값을 할당해서 쓰지않고 바로 return하여 그 값을 쓰는 방식도 생각해 볼 수 있다.
Object.values(object)을 통해서 열거가능한 값을 배열로 리턴 할 수 있다.
function solution(clothes) {
return Object.values(clothes.reduce((a,b)=> {
a[b[1]] = (a[b[1]] || 0)+1;
return a;
},{})).reduce((c,d)=>{
return (c*(d+1));
},1)-1
}
풀었던 코드를 블로그로 옮기면서 다시 읽어보니 변수나 메소드 명을 제대로 지어주지 않은 것이 눈에 보였다. 연습에도 변수명 제대로 쓸것!🙆🏻♀️