Skip to content

[Bona1122] 25.01.02#8

Merged
JooKangsan merged 5 commits intocodingTestStd:mainfrom
bona1122:bona1122
Jan 9, 2025
Merged

[Bona1122] 25.01.02#8
JooKangsan merged 5 commits intocodingTestStd:mainfrom
bona1122:bona1122

Conversation

@bona1122
Copy link
Collaborator

@bona1122 bona1122 commented Jan 3, 2025

[배열]

배열 메서드들을 사용하며 리마인드 했던 내용들과 문제를 풀며 배열 문제에서 얻은 인사이트를 정리했습니다.

  • splice 메서드의 반환값은 수정된 원본 배열이 아니라, splice를 통해 제거된 요소들의 배열이다.
  • 1차원 배열을 Reshape(배열의 차원이나 형태를 변경하면서 데이터의 순서는 유지하는 연산)하는 알고리즘
// 1차원 인덱스를 2차원 행렬 좌표로 변환하는 알고리즘
function getMatrixCoordinate(index, n) {
   return {
       row: Math.floor(index / n), // 행 = 인덱스를 열 크기로 나눈 몫
       col: index % n             // 열 = 인덱스를 열 크기로 나눈 나머지
   };
}
console.log(getMatrixCoordinate(4, 3)); // { row: 1, col: 1 }

📌 푼 문제


📝 간단한 풀이 과정

제일 작은 수 제거하기

  • 제일 작은 수를 찾아내고, 인덱스를 구해 해당인덱스를 제외하는 방식을 사용했습니다.
const solution = (arr) => {
  if (arr.length <= 1) return [-1];
  const min = Math.min(...arr);
  const minIdx = arr.indexOf(min);
  arr.splice(minIdx, 1); // splice는 제거된 요소들의 배열을 반환하므로 return arr.splice(minIdx, 1);는 틀리게된다.
  return arr;
};

행렬의 덧셈

  • map 메서드에 전달되는 매핑 함수의 인자 중, 인덱스 값을 활용하였습니다.
const solution = (arr1, arr2) => {
  const add = (a, b) => a + b;
  const addArrays = (a, b) => a.map((item, idx) => add(item, b[idx]));

  return arr1.map((row, i) => addArrays(row, arr2[i]));
};

행렬의 곱셈

  • 행렬의 곱셈의 결과값을 담을 행렬을 먼저 만들어 두고, 결과값 행렬의 값을 공식에 맞게 채우는 방식으로 구현했습니다.

행렬의 곱셈 공식

  • 첫 번째 행렬의 열 수 = 두 번째 행렬의 행 수
  • 결과 행렬의 크기 = (첫 번째 행렬의 행 수) × (두 번째 행렬의 열 수)

두 행렬 $A_{m×n}$$B_{n×p}$의 곱셈 결과 $C_{m×p}$ 는 다음과 같이 계산:
$C_{ij} = \sum_{k=1}^n A_{ik} \times B_{kj}$

두 행렬:

A = | a11  a12 |
    | a21  a22 |

B = | b11  b12 |
    | b21  b22 |

결과 행렬 C의 각 요소는:
$C_{11} = a_{11}b_{11} + a_{12}b_{21}$
$C_{12} = a_{11}b_{12} + a_{12}b_{22}$
$C_{21} = a_{21}b_{11} + a_{22}b_{21}$
$C_{22} = a_{21}b_{12} + a_{22}b_{22}$

const solution = (arr1, arr2) => {
  // 결과 행렬 크기 생성
  const result = Array.from({ length: arr1.length }, () =>
    Array(arr2[0].length).fill(0)
  );

  // 행렬 요소 하나씩 값 만들기
  return result.map((row, i) =>
    r.map((item, j) => {
      return arr1[i].reduce((acc, cur, k) => acc + cur * arr2[k][j], 0);
    })
  );
};

교점에 별 만들기

크래머 공식

두 직선의 교점을 구하는 공식이다.

두 직선 방정식:
$ax + by + e = 0$
$cx + dy + f = 0$

교점 좌표:
$x = (bf - ed) / (ad - bc)$
$y = (ec - af) / (ad - bc)$

주의: $ad - bc = 0$: 평행 또는 일치

  • 모든 직선의 조합을 구해야해서, dfs를 떠올렸는데 2개를 고르는 것이라 간단하게 2중 for문으로 처리했습니다.
  • 크래머 공식을 적용해서 교점을 구하고
  • Math.floor와의 비교로 정수를 판단했습니다.
function solution(line) {
  const points = new Set();

  // 교점 찾기(크래머 공식)
  for (let i = 0; i < line.length - 1; i++) {
    for (let j = i + 1; j < line.length; j++) {
      const [a, b, e] = line[i];
      const [c, d, f] = line[j];

      const denominator = a * d - b * c;
      if (denominator === 0) continue;

      const x = (b * f - e * d) / denominator;
      const y = (e * c - a * f) / denominator;

      if (x === Math.floor(x) && y === Math.floor(y)) {
        points.add(`${x},${y}`); // set에서 중복없이 하려고 배열 대신 문자열 이용 -> 나중에 다시 변환 필요
      }
    }
  }

  // 좌표 배열로 변환, 최대/최소 구하기
  const coords = Array.from(points).map((p) => p.split(",").map(Number));
  const [minX, maxX] = [
    Math.min(...coords.map((p) => p[0])),
    Math.max(...coords.map((p) => p[0])),
  ];
  const [minY, maxY] = [
    Math.min(...coords.map((p) => p[1])),
    Math.max(...coords.map((p) => p[1])),
  ];

  // 격자 생성, 별 찍기
  const grid = Array(maxY - minY + 1)
    .fill()
    .map(() => Array(maxX - minX + 1).fill("."));
  coords.forEach(([x, y]) => {
    grid[maxY - y][x - minX] = "*";
  });

  return grid.map((row) => row.join(""));
}

n^2 배열 자르기

아래의 핵심사항을 파악하는 것이 어려웠습니다.

  • 1차원 배열을 인덱스를 이용해서 (n,n) 행렬로 변환하는 관점(Reshape)
  • i = 1,2, ..., n 에 대해 1행1열부터 i행i열까지의 영역 내의 빈 칸을 숫자 i로 채우는 것이 Math.max(row, col)인 규칙을 갖는다는 것
function solution(n, left, right) {
  return Array.from({ length: right - left + 1 }, (_, idx) => {
    const i = left + idx;
    const row = Math.floor(i / n);
    const col = i % n;
    return Math.max(row, col) + 1;
  });
}

Copy link
Collaborator

@oh-chaeyeon oh-chaeyeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고많으셨습니다!!😊 코드리뷰하면서 많이 배우고 갑니다~

if (arr.length <= 1) return [-1];
const min = Math.min(...arr);
const minIdx = arr.indexOf(min);
arr.splice(minIdx, 1); // splice는 제거된 요소들의 배열을 반환하므로 return arr.splice(minIdx, 1);는 틀리게된다.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 filter를 사용해서 문제를 풀었는데, splice를 이용해서 푸는 방법도 알아갑니다!! arr이 [4, 3, 2, 1]일때, arr.splice(minIdx, 1);는 1일텐데, return arr.splice(minIdx, 1);를 하면 1를 제거한 배열이 아닌 1를 반환해서 틀리는군요....잘 알아둬야겠군요!!

Comment on lines +2 to +5
const add = (a, b) => a + b;
const addArrays = (a, b) => a.map((item, idx) => add(item, b[idx]));

return arr1.map((row, i) => addArrays(row, arr2[i]));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add함수랑 addArrays함수를 만들어서 문제를 푼 부분에서 이런 방식으로 푸니깐 더 코드가 깔끔해보이네요👍👍 배우고 갑니다~


// 행렬 요소 하나씩 값 만들기
return result.map((row, i) =>
r.map((item, j) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r.map -> row.map 으로 변경해야 할것 같습니다:)

Comment on lines +23 to +31
const coords = Array.from(points).map((p) => p.split(",").map(Number));
const [minX, maxX] = [
Math.min(...coords.map((p) => p[0])),
Math.max(...coords.map((p) => p[0])),
];
const [minY, maxY] = [
Math.min(...coords.map((p) => p[1])),
Math.max(...coords.map((p) => p[1])),
];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고 map과 Math.min(), Math.max()가 각각 두 번 호출하기에, 각 좌표 배열을 두 번 순회해야 하는 부분을 reduce메서드 사용하면 한번의 순회로 모든 값을 처리할수 있어서 이런식으로 개선해보는것이 어떨까 생각해봤습니다!

const coords = Array.from(points).map((p) => p.split(",").map(Number));
const [minX, maxX, minY, maxY] = coords.reduce(
  ([minX, maxX, minY, maxY], [x, y]) => [
    Math.min(minX, x),
    Math.max(maxX, x),
    Math.min(minY, y),
    Math.max(maxY, y),
  ],
  [Infinity, -Infinity, Infinity, -Infinity]
);

@JooKangsan JooKangsan merged commit 1bc8b59 into codingTestStd:main Jan 9, 2025
0 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants