프로그래머스)최소직사각형

minji jeon·2022년 7월 19일
0

알고리즘

목록 보기
25/29
post-thumbnail

1. 문제

명함 지갑을 만드는 회사에서 지갑의 크기를 정하려고 합니다. 다양한 모양과 크기의 명함들을 모두 수납할 수 있으면서, 작아서 들고 다니기 편한 지갑을 만들어야 합니다. 이러한 요건을 만족하는 지갑을 만들기 위해 디자인팀은 모든 명함의 가로 길이와 세로 길이를 조사했습니다.

아래 표는 4가지 명함의 가로 길이와 세로 길이를 나타냅니다.

명함 번호 가로 길이 세로 길이
1 60 50
2 30 70
3 60 30
4 80 40
가장 긴 가로 길이와 세로 길이가 각각 80, 70이기 때문에 80(가로) x 70(세로) 크기의 지갑을 만들면 모든 명함들을 수납할 수 있습니다. 하지만 2번 명함을 가로로 눕혀 수납한다면 80(가로) x 50(세로) 크기의 지갑으로 모든 명함들을 수납할 수 있습니다. 이때의 지갑 크기는 4000(=80 x 50)입니다.

모든 명함의 가로 길이와 세로 길이를 나타내는 2차원 배열 sizes가 매개변수로 주어집니다. 모든 명함을 수납할 수 있는 가장 작은 지갑을 만들 때, 지갑의 크기를 return 하도록 solution 함수를 완성해주세요.

2. 접근

확실히 중급단계로 갈수록 문제의 길이가 길어지고
논술형 느낌으로 변해가고 있다.

우선 문제가 어려울때는 최대한 직관적으로 풀려고 노력했다.
직관적으로 푸는게 기발한 발상을 해주지는 못하지만
접근은 쉽기때문에 가장 답에 가까워 질수 있는 방법중 하나인거 같다.

  1. 이중배열이므로 배열안에 배열 꺼내기
  2. 가로를 세로로 바꿀수 있어야 하니 작은수- 큰수정렬
  3. 최댓값구하기 어떻게 구할것인가...ㅜㅜㅜㅜ
    하나하나 꺼내서 배열로 만들어서 최댓값 구하기..?(math, min)
    아니면 합쳐서 짝수번에서 최댓값/홀수번에서 최댓값 구하기

3. 내답

function solution(sizes) {
  var answer = 0;
  let row = [];
  let column = [];

  [...sizes].map((x) => {   //[5 ,6]   [6,1]  이렇게 하나씩 출력됨
    x.sort((a, b) => a - b);
    row.push(x[0] * 1);   // [5] ,[6]..
    column.push(x[1] * 1);
  });

  return Math.max(...row) * Math.max(...column);
}

  ])
);

스프레드 문법과 맵을 사용하여 배열 안에 배열을 하나씩 넣어주도록 하였다.
사실 새로운 배열에 푸쉬를 할거였다면 foreach함수를 써도 상관없었을거 같다.
맵의 요소 x를 오름차순으로 정렬을 해준뒤 가로에 해당하는 인덱스만, 세로에 해당하는 인덱스만
새로운 row변수, column.변수에 추가해주었다. 이때 x값이 문자열로 인식되어 1을 곱해준 뒤 푸시를 해주었다.
마지막으로 해당배열에서 최댓값을 서로곱하게 해주었다.

우선 과정이 많다보니 출력하는데 시간이 꽤 시간이 오래걸렸다. 그래서 다른 답들도 공부를 해보았다.

그리고 맵안에서 각 요소들이 정렬이 되도록
이런 상황에서는 스프레드 문법이 꽤 유용한거 같다.

2. 남의 답

function solution(sizes) {
    const [hor, ver] = sizes.reduce(([h, v], [a, b]) => [Math.max(h, Math.max(a, b)), Math.max(v, Math.min(a, b))], [0, 0])
    return hor * ver;
}

이문제를 한줄에 풀었다고...?
가히 충격적이다.
어떻게 풀었는지 뜯어보자..!
우선
const [a ,b] = [array] 방식을 사용하였다.
이를 구조분해 할당문법이라 한다.
이때 array[0]=a에 값이 할당이 된다.
reduce함수의 기본구조는 arr.reduce((a,b)=> a+b) 이다
여기서 a는 [h, v] 즉 sizes[0]이다. b는 [a, b] 즉 sizes[0]이다.
이제 콜백함수안에서 요리조리 요리를 시작했는데
Math.max(h, Math.max(a, b))의 의미는
최댓값(sizes[0][0], 최댓값(sizes[0][0],sizes[0][1]))
최댓값(sizes[0][0], 최댓값(sizes[1][0],sizes[1][1]))
이렇게 쭉쭉쭉 배열을 나가면서 최댓값을 찾는 과정이다.
그렇게 나온 최댓값 h,v 를 곱하였다.

function solution(sizes) {
    let w = 0;
    let h = 0;
    sizes.forEach(s => {
        const [a, b] = s.sort((a,b) => a-b);
        if (a > h) h = a;
        if (b > w) w = b;
    });

    return w * h;
}

이 답도 생각보다 깔끔하게 풀어내서 가져왔다.
foreach함수로 배열을 돌면서 배열하나씩 처리를 해주는데
여기서도 const [a ,b] = [array] 이방식을 사용하였다.
이중배열일때 사용하면 간편하게 배열 안에 값을 가져올 수 있다.
우선 나와 비슷하게 sort를 사용하여 오름차순으로 정렬을 한뒤
a > 0 => a =0
b> 0 => b =0 이렇게 연쇄적으로 if문을 사용하여 각 배열의 최댓값이 w, h에 할당되도록 하였다. 이방법 또한 잘 알고 있다가 사용해야겠다.

function solution(sizes) {
    const newSizes = sizes.map(e => e.sort((a, b) => a - b));
    return Math.max(...newSizes.map(e => e[0])) * Math.max(...newSizes.map(e => e[1]));
}

map함수는 조건에 맞도록 배열을 새롭게 반환시켜주기 때문에 newsizes함수에 할당을 해주고
e[0]중에 최댓값과 e[1]중에 최댓값을 곱해줬다.
map을 잘만 이용하면 이중함수를 굳이 꺼내지 않고도 값을 추출해내는것이 가능함을 이번 문제를 통해 깨달았다.

오늘배운것

이중배열을 다룰때는 스프레드,구조분해 할당문법, map을 유용하게 사용해보자

profile
은행을 뛰쳐나와 Deep Dive in javascript

0개의 댓글