본문 바로가기
코테연습

61. 최소직사각형 Javascript

by hxunz 2022. 6. 14.

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

 

코딩테스트 연습 - 최소직사각형

[[10, 7], [12, 3], [8, 15], [14, 7], [5, 15]] 120 [[14, 4], [19, 6], [6, 16], [18, 7], [7, 11]] 133

programmers.co.kr

 

 

1. 문제에 대한 이해

  • 우리가 풀어야 할 문제는 무엇인가?
     - 모든 명함을 수납할 수 있는 가장 작은 지갑을 만들 때, 지갑의 크기를 return
  • 주어진 자료는 무엇인가?
     - 모든 명함의 가로 길이와 세로 길이를 나타내는 2차원 배열 sizes
  • 조건은 무엇인가?
     -
    sizes의 길이는 1 이상 10,000 이하입니다.
    • sizes의 원소는 [w, h] 형식입니다.
    • w는 명함의 가로 길이를 나타냅니다.
    • h는 명함의 세로 길이를 나타냅니다.
    • w와 h는 1 이상 1,000 이하인 자연수입니다.

2. 계획

 

  1. 주어진 sizes 2차원 배열내 각 배열들의 0번째 숫자가  2차원 배열내 각 배열들의 1번째 숫자 보다 작으면
    width에 2차원 배열내 각 배열들의 1번째 숫자들을 넣고
    height에 2차원 배열내 각 배열들의 0번째 숫자들을 넣는다
  2. 그렇지 않으면
    width에 2차원 배열내 각 배열들의 0번째 숫자들을 넣고
    height에 2차원 배열내 각 배열들의 1번째 숫자들을 넣는다
  3. 이 배열들을 각각 내림차순으로 정렬한다
  4. width의 0번째 배열과 height의 0번째 배열을 곱한다
  5. 이 값을 리턴한다.

 

3. 실행

  • 풀이 계획을 실행하고, 각 단계가 올바른지 점검하라.

const solution = (sizes) => {
  let width = [];
  let height = [];

  for (i = 0; i < sizes.length; i++) {
    if (sizes[i][0] < sizes[i][1]) {
      width = [...width, sizes[i][1]]
      height = [...height, sizes[i][0]]
    } else {
      width = [...width, sizes[i][0]]
      height = [...height, sizes[i][1]]
    }
  };

  return width.sort((a,b) => b-a)[0] * height.sort((a,b) => b-a)[0]
};

test('최소직사각형', () => {
  expect(solution([[60, 50], [30, 70], [60, 30], [80, 40]])).toEqual(4000);
});

 

4. 반성

  • 문제를 다른 방식으로 해결할 수 있는가?
     - map이나 reduce를 사용해서 더 깔끔하게 작성할 수 있을것같다.


const solution = (sizes) => {
  const square = sizes.map((it) => {
    return (it[0] < it[1]) ? [it[1], it[0]] : it;
  });

  const width = Math.max(...square.map((it) => it[0]));
  const height = Math.max(...square.map((it) => it[1]));

 return width * height;

 


 

const solution = (sizes) => {
  const square = sizes.map((it) => {
    return (it[0] < it[1]) ? [it[1], it[0]] : it;
  });

  const maxSquare = square.reduce((acc, cur) => {
    const width = acc[0] < cur[0] ? cur[0] : acc[0];
    const height = acc[1] < cur[1] ? cur[1] : acc[1];
    return [width, height];
  }, [0, 0]);

  return maxSquare[0] * maxSquare[1];
};

 

 

 

 

처음에는 2차원 배열을 1차원 배열로 만들고 가로세로 구분없이 내림차순 정렬했을때
가장 큰 값이 인덱스 0번째 수랑
이 배열의 길이를 2로 나눈 수를 나타내는 인덱스의 수를 곱하는것으로 계산을 했었다.

이때 테스트 통과가 반밖에 안되었고 어떤 예외가 있을지 고민해보았다. 
어떤 값이 들어왔을때 통과가 안되는지 알 수 없어서 답답했다. 
그런데 주어진 배열이 [[60,50],[70,70],[60,30],[80,40]]인 경우에 에러가 나는 것을 알 수 있었다.

그래서 가로의 길이와 세로의 길이를 구분해야겠다고 생각했고 다시 문제를 풀어보았다.
처음에는 익숙한 for문을 사용해서 테스트가 전부 통과가 되었다.

그런데 for문으로 작성한 코드가 반복이 많아 보여서 다른 방법이 없을까 고민해보았다. 
map이나 reduce를 이용할 수 있을것같은데 
reduce로 푸는 방법은 잘 생각이 나지 않아서 우선, map을 사용해서 풀어보았고 
reduce를 사용해보기도 했는데 이렇게 사용하는게 맞는건지는 잘 모르겠다,,
좀 더 고민을 해봐야겠다. 

'코테연습' 카테고리의 다른 글

63. 다트 게임  (0) 2022.06.15
62. 비밀지도 Javascript  (0) 2022.06.14
60.약수의 개수와 덧셈 Javascript  (0) 2022.06.11
59. 예산 Javascript  (0) 2022.06.08
58. 실패율 Javascript  (0) 2022.06.08

댓글