티스토리 뷰

반응형

 

프로그래머스 - 위장

 

문제는 위 링크에서 볼 수 있다. 문제에 대한 해설보다는 기억하고 싶은 개념, 사고, 문법을 기록하는 글이다. 

답안은 맨 아래에 표기해 두었다.

 


 

1. reduce() 메서드로 object형태 만들기 

reduce()는 자신을 호출한 배열의 요소를 순화하면서 인수로 전달된 콜백함수를 반복 호출한다. 그리고 콜백함수의 반환값을 다음 순회 시에 콜백 함수의 첫 번째 인수로 전달하면서 콜백 함수를 호출하여 하나의 결과값을 만들어 반환한다. 

해시 관련 문제는 key:value 형태로 변환하는 형식으로 풀어야하는 것 같다. 저번 풀이에도 reduce()를 이용했는데 이번에도 같은 방식으로 시작했다. 이 때 for문을 써도 되지만, reduce()를 쓰면 더 간편하게 object형태로 만들 수 있다. 

 

 

-for 문

obj[key] = value 형태를 이용해 문제 조건에서 주어진 값을 대입한 것이다. 

let obj = [];

for (let i = 0; i < clothes.length; i++) {
obj[clothes[i][1]] = (obj[clothes[i][1]] || 0) + 1;
}

// [ headgear: 2, eyewear: 1 ]

 

 

- reduce()

reduce()의  기본 공식에 맞게 넣었다.

obj 형태로 {} 초기값을 설정해주고, cur[1]은 clotes[i][1] 부분을 key로 만들겠다는 것을 의미한다.

acc[cur[1]]에 해당하는 값이 없으면 value가 1이되고, 값이 존재하면 그 값에 1을 더해주면서 obj = {} 에 누적(accumulator)되는 것이다.

이에 따른 결과는obf = [ headgear: 2, eyewear: 1 ] 가 된다.

  let obj = clothes.reduce((acc, cur) => {
    acc[cur[1]] = acc[cur[1]] ? acc[cur[1]] + 1 : 1;
    return acc;
  }, {});
  
  // [ headgear: 2, eyewear: 1 ]

또는 이런식으로 obj , {} 를 초기값으로 누적하여 리턴값을 바로 보낼 수 도 있다.

 let obj = clothes.reduce((obj, type) => (
    (obj[type[1]] = obj[type[1]] ? obj[type[1]] + 1 : 1), obj
    ),{})

 

경우의 수를 구하는 공식은 쉽다. 아래의 테스트케이스에서 headgear, eyewear을 무조건 한가지씩 쓰고 나가야한다면 2 * 1 = 2가지의 경우의 수가 있다. 

[["yellowhat", "headgear"], ["bluesunglasses", "eyewear"], ["green_turban", "headgear"]]
1. headgear : yellowhat , eyewear : bluesunglasses
2. headgear : green_turban , eyewear : bluesunglasses

 

 

하지만 문제 조건을 보면 하루에 최소 한 개 의상을 입는다고 한다. 테스트케이스에 있는 headgear, eyewear중 하나만 쓰고  나가도 된다는 소리이다.  따라서 각 항목에서 1을 더하면  (2+1) * (1+1) = 3 * 2 = 6 가지의 경우의 수가 나오는데. 이는 아무 것도 입지 않는 경우의 수도 포함됨으로 마지막 값에서 -1를 해주면 되는 일이다. 

3. headgear : yellowhat 
4. headgear : green_turban 
5. eyewear : bluesunglasses
6. nothing

 

이 부분을 놓치면 답이 나오지 않는다. 여담이지만 그래서 의상의 종류가 악세사리로 되어있구나- 라는 생각을 했다..  상의하의는 하나는 입고나가야지~~

 

  for (let key in obj) {
    answer *= obj[key] + 1;
  }
  
 return answer - 1;

 

 


 

구현 능력 

카테고리가 나누어져 있어서 해시인 것을 알고 보니 key:value형태로 나눠야한 다는 것을 알았다. 

실제 문제가 나오면 카테고리가 따로 나누어져 있지 않을텐데 문제를 잘 읽고 어떤 개념을 요구하는지 잘 파악해야할 것 같다. 

그리고 해시문제임을 알아차렸다면! 또 리턴해야하는 값이 개수라면 무조건 reduce()로 key와 value를 나누고, 각 value에 0이나 1을 할당하여 중복된 key에 값을 더하는 식으로 접근해야함을 알았다. 

 

reduce()로 저번 큐 관련 문제에서는 배열의 합계를 구했고, 이번 해시 관련 문제들에서는 배열을 객체형태로 만들었다. 이 것 말고도 다양한 활용법이 있던데, 여러 활용법을 문제를 풀며 익히도록 해야겠다. 

 

 


 

답안 

 

function solution(clothes) {
  let answer = 1;

  let obj = clothes.reduce((acc, cur) => {
    acc[cur[1]] = acc[cur[1]] ? acc[cur[1]] + 1 : 1;
    return acc;
  }, {});


  for (let key in obj) {
    answer *= obj[key] + 1;
  }

  return answer - 1;
}

 

반응형