본문 바로가기
코딩 문제/프로그래머스 [ JavaScript ]

[ 프로그래머스 / JavaScript ] 최소직사각형

by CODESIGN 2022. 9. 18.

https://school.programmers.co.kr/learn/courses/30/lessons/86491

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

문제 설명


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

아래 표는 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 함수를 완성해주세요.

 

 

제한사항


  • sizes의 길이는 1 이상 10,000 이하입니다.
    • sizes의 원소는 [w, h] 형식입니다.
    • w는 명함의 가로 길이를 나타냅니다.
    • h는 명함의 세로 길이를 나타냅니다.
    • w와 h는 1 이상 1,000 이하인 자연수입니다.

 

 

입출력 예


 

sizes result
[[60, 50], [30, 70], [60, 30], [80, 40]] 4000
[[10, 7], [12, 3], [8, 15], [14, 7], [5, 15]] 120
[[14, 4], [19, 6], [6, 16], [18, 7], [7, 11]] 133

 

 

입출력 예 설명


입출력 예 #1
문제 예시와 같습니다.

 

입출력 예 #2
명함들을 적절히 회전시켜 겹쳤을 때, 3번째 명함(가로: 8, 세로: 15)이 다른 모든 명함보다 크기가 큽니다. 따라서 지갑의 크기는 3번째 명함의 크기와 같으며, 120(=8 x 15)을 return 합니다.

 

입출력 예 #3
명함들을 적절히 회전시켜 겹쳤을 때, 모든 명함을 포함하는 가장 작은 지갑의 크기는 133(=19 x 7)입니다.

 

 

나의 문제 풀이


이 문제에서는 가로와 세로를 구분 지을 필요가 없다. 명함 넣는 방향을 바꿀 수 있기 때문이다.

그래서 나는 가로를 제일 큰 값으로 설정하고 세로는 큰 값이 아닌 숫자는 세로의 길이보다 크면 세로의 길이로 설정해주도록 했다.

 

첫 sizes에서 가로와 세로가 주어질때 가로와 세로의 길이를 비교해 더 큰 값을 가로(row)에 저장하였다.

그 후로 sizes의 배열을 돌면서 가로와 세로의 길이중 더 긴 길이를 row와 비교하여 더 큰값이 row로 설정하였다.

나머지  min 값은 현재 세로의 길이보다 작다면 pass~ 크다면 세로의 길이로 설정해주었다.

그리고 마지막에 row와 col 값을 곱하여 return 했다.

 

function solution(sizes) {
    // row가 항상 더 크게 설정
    var row = Math.max(sizes[0][0],sizes[0][1]);
    var col = Math.min(sizes[0][0],sizes[0][1]);

    for (let i = 1; i < sizes.length; i++) {
        var max = Math.max(sizes[i][0],sizes[i][1]);
        var min = Math.min(sizes[i][0],sizes[i][1]);
        if (row < max) { //현재 row값 보다 큰 경우 변경해준다
                row = max;
        }
        if (col < min) { //현재 col값 보다 큰 경우 변경해준다
                col = min;
        }
    }
    return row*col;
}

 

 

 

다른 풀이


코드가 훨씬 간결하고 runtime이 빠르다.

reduce는 정말 다양한 방법으로 쓸수 있는것 같다.

 

[h, v] 는 accumulator(누적 값)으로 여기서도 가로와 세로의 기준으로 문제를 풀기보다

sizes의 배열의 가로,세로가 주어질때, 저 둘의 값중 큰값을 h와 비교하여 큰 값을 h에 저장하고

저 둘의 값중 작은 값을 v와 비교하여 큰 값을 v에 저장하였다.

 

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;
}

 

 

[ 자바스크립트 ] reduce() 함수 이해하기

구문 arr.reduce(callback[, initialValue]); reduce() 함수는 네 개의 인자를 가진다. 누산기 (acc) 현재 값 (cur) 현재 인덱스 (idx) 원본 배열 (src) reduce() 함수의 반환 값은 누산기에 할당되고, 누산기는..

codesign.tistory.com

 

 

 

 

 

댓글