[프로그래머스] 위장 (해시 LEVEL2)

devCecy·2022년 3월 22일
0

알고리즘

목록 보기
4/5
post-thumbnail

프로그래머스 코딩테스트 연습의 해시-위장 문제

문제

스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.

예를 들어 스파이가 가진 옷이 아래와 같고 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다.

종류	이름
얼굴	동그란 안경, 검정 선글라스
상의	파란색 티셔츠
하의	청바지
겉옷	긴 코트

스파이가 가진 의상들이 담긴 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

나의 풀이 1

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

위와 같이 풀고나니 첫 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
}

나의 풀이 3

해시 첫번째 문제에서 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
}

풀었던 코드를 블로그로 옮기면서 다시 읽어보니 변수나 메소드 명을 제대로 지어주지 않은 것이 눈에 보였다. 연습에도 변수명 제대로 쓸것!🙆🏻‍♀️

profile
🌈그림으로 기록하는 개발자🌈

0개의 댓글