PS/Programmers

Programmers / Level 2 / 테이블 해시 함수 / JS

KimMinJun 2024. 7. 18. 12:49

문제 간단설명

다음과 같은 과정을 거쳐서 해시값을 반환하면 된다.

  1. 테이블의 튜플을 col 번째 컬럼의 값을 기준으로 오름차순 정렬을 하되, 만약 그 값이 동일하면 기본키의 첫 번째 컬럼의 값을 기준으로 내림차순 정렬합니다.
  2. 정렬된 데이터에서 S_i를 i번째 행의 튜플에 대해 각 컬럼의 값을 i로 나눈 나머지들의 합으로 정의합니다.
  3. row_begin <= i <= row_end인 모든 S_i를 누적하여 bitwise XOR 한 값을 해시 값으로서 반환합니다.

 

제한 사항

  • 1 <= data의 길이 <= 2,500
  • 1 <= data의 원소의 길이 <= 500
  • 1 <= data[i][j] <= 1,000,000
    • data[i][j]는 i + 1 번째 튜플의 j + 1 번째 컬럼의 값을 의미합니다.
  • 1 <= col <= data의 원소의 길이
  • 1 <= row_begin <= row_end <= data의 길이

 

성공 코드

function solution(data, col, row_begin, row_end) {
  // 1. 테이블의 튜플을 col 번째 컬럼의 값을 기준으로 오름차순 정렬을 하되,
  //    만약 그 값이 동일하면 기본키인 첫 번째 컬럼의 값을 기준으로 내림차순 정렬합니다.
  data.sort((a, b) => {
    if (a[col - 1] === b[col - 1]) {
      return b[0] - a[0];
    }
    return a[col - 1] - b[col - 1];
  });

  // 2. 정렬된 데이터에서 S_i를 i번째 행의 튜플에 대해
  //    각 컬럼의 값을 i로 나눈 나머지들의 합으로 정의합니다.
  const S = [];
  for (let i = 0; i < data.length; i++) {
    let S_i = 0;
    for (let j = 0; j < data[i].length; j++) {
      S_i += data[i][j] % (i + 1);
    }

    S.push(S_i);
  }

  // 3. row_begin <= i <= row_end 인 모든 S_i를 누적하여
  //    bitwise XOR 한 값을 해시 값으로서 반환합니다.
  let result = S[row_begin - 1];
  for (let i = row_begin; i < row_end; i++) {
    result ^= S[i];
  }

  return result;
}

 

다른 사람의 코드

function sort(a, b, col) {
    return a[col - 1] - b[col - 1] || b[0] - a[0];
}

function solution(data, col, row_begin, row_end) {
    data.sort((a, b) => sort(a, b, col));
    return data
        .map((row, i) => row.reduce((acc, col) => acc + (col % (i + 1)), 0))
        .slice(row_begin - 1, row_end)
        .reduce((acc, val) => acc ^ val, 0);
}

 

JS의 메소드들을 가장 잘 이용한 풀이가 아닐까 싶다. 하지만 그것 외에도 sort 함수를 따로 정의한 부분이 좋은 코드인것 같다. 처음엔 이해가 잘 가지 않았는데, 다음과 같다.

 

일단 OR( || ) 연산은 둘 중 하나가 참이라면 true를 반환한다. 따라서, OR 연산자 앞의 조건이 참이라면, 뒤는 판단하지 않는다. 하지만 falsy 한 값이라면 뒤까지 판단한다.

 

0은 falsy 한 값이기 때문에, 위 코드에서 앞의 조건이 0이라면, 즉 a[col - 1]과 b[col - 1]이 같은 값이라면 0이 되면서 앞은 falsy 한 값이 되어 뒷 연산이 실행되는것이다. 따라서 문제에서 주어진 정렬조건을 한줄로 나타낸것이다.

 

나머지는 map을 이용한 엘리먼트들의 값을 바꾸기, reduce를 이용해 합을 구하기, slice를 이용해 배열을 자르는 JS의 배열 메서드들을 잘 활용한 코드인 것 같다.