Practice for coding test

프로그래머스 - Level 1. 최소직사각형 / JavaScript (js)

Gray Park 2023. 2. 6. 20:34
728x90
반응형

square dancing

문제설명 - 최소직사각형

문제분석

모든 명함에는 가로길이와 세로길이가 존재하며, 가로 또는 세로의 길이가 각각 가장 긴 명함의 변을 구해 가장 작은 지갑의 면적을 리턴하는 문제이다. 말이 조금 어려운 거 같아서 풀어보자면 다음과 같다.

  1. 모든 명함에는 가로길이와 세로길이가 있다.
  2. 일반적인 명한은 가로 길이가 더 길지만, 간혹 세로길이가 더 긴 명함도 존재한다.
  3. 세로길이가 더 긴 명함을 옆으로 돌려서(세로길이와 가로길이를 스왑해서) 보관할 수 있다.
  4. 위 모든 경우를 포함하는 동시에, 입력된 모든 크기의 명함을 보관할 수 있는 가장 작은 지갑을 만들어야 한다.
  5. 결과값은 명함의 가장 긴 가로길이 x 가장 긴 세로길이여야 한다. (이때 3번이 이미 적용된 상태여야 한다.)

 

문제를 단순화 했으니 이해하기 쉽게 코드를 짜보자.

 

이해하기 쉽게 코드작성하기

function solution(sizes) {
    var answer = 0;
    
    // 입력으로 주어진 각 요소(배열)을 긴 길이와 짧은 길이로 정렬
    const sortedSizes = sizes.map(elements => {
        const [head, tail] = elements;
        return head > tail ? elements : [tail, head];
    });
    
    // 가로길이와 세로길이 각각에서 가장 긴 변을 찾음
    let max = -Infinity,
          min = -Infinity;
    sortedSizes.forEach(elements => {
        const [large, small] = elements;
        if(large > max) {
            max = large;
        }
        if(small > min) {
            min = small;
        }
    });
    
    // 가장 작은 지갑의 너비를 리턴
    answer = max * min;
    
    return answer;
}

코드 설명

이 문제는 하나의 명함에 대해서 먼저 고민하면 쉽게 풀 수 있다. 하나의 명함은 항상 긴 변과 짧(거나 같)은 변이 존재한다. 따라서 그 중 긴 변을 첫번째 요소로, 짧(거나 같)은 변을 두번째 요소로 하는 튜플로 변환한다. 그리고 이 튜플을 모두 순회하면서 긴 변중 가장 긴 변, 짧은 변 중 가장 긴 변을 구하면 된다.

코드를 조금 더 간결하게 써보면 다음 처럼도 작성할 수 있다.

function solution(sizes) {
    return sizes
    	.map(size => size[0] > size[1]
			? size
			: size.reverse())
        .reduce((a, c) => {
        	if(a[0] < c[0]) a[0] = c[0];
        	if(a[1] < c[1]) a[1] = c[1];
        	return a;
    	}, [-Infinity, -Infinity])
    	.reduce((a,c) => a*c);
}

위 코드에서 특이한 점은 sort 대신에 reverse를 썼다는 건데, 사실 튜플이라 이렇게 쓰나 저렇게 쓰나 상관이 전혀 없다. 개인적인 선호도에 따라 이해하기 편하려고 reverse를 썼다.

 

map을 통해 정렬을 마쳤으므로, 첫번째 reduce에서는 각 index별 가장 긴 변을 가진 튜플을 생성해냈다.

그리고 두번째 reduce(라고 해봤자 튜플)로 두 값을 곱해 너비를 찾아 리턴하면 끝

728x90
반응형