PS/제코베 JS 100제

제코베 JS 100제 / 90 / 같은 의약 성분을 찾아라!

KimMinJun 2022. 10. 4. 17:28

의약품 성분이 총 8개인 약품들이 있습니다. 예를 들어 다음 데이터는 총 8개의 성분을 갖습니다.

 

판콜비 = 'ABCDEFGH'

넥타이레놀 = 'EFGHIJKL'

 

특정 약품 A의 성분이 공개되었을 때, 이와 유사한 성분을 가진 데이터들의 출력을 구하는 문제입니다.

 

입력 : 'ABCDEFGH' 4

데이터 : 'EFGHIJKL', 'EFHGIJKM', 'EFGHIJKZ' 등 1만 개의 데이터

출력 : 'EFGHIJKL', 'EFGHIJKM', 'EFGHIJKZ' 등 4개의 요소가 같은 약품 전부(4개 이상이 아니며 같은 요소가 4개인 것을 출력해야 합니다.)

 

* 해당 문제는 시간제한이 있습니다.

* 제약 데이터의 성분은 중복이 될 수 없습니다.

(예를 들어 'AAABBBAB'와 같은 데이터는 없습니다.)

 

/**
 * 기준성분, 같은 요소의 개수가 공백으로 구분된 문자열인 INPUT과
 * 비교할 데이터들의 배열인 DATA_ARR를 받아서
 * 기준성분, 그리고
 * 인자로 들어온 개수만큼 성분이 같은 데이터를 반환 해주는 함수
 *
 * @param {string} INPUT 기준성분, 개수가 공백으로 구분된 문자열
 * @param {string[]} DATA_ARR 데이터들이 담긴 배열
 * @returns {string[]} 인자로 들어온 개수만큼 같은 데이터들 return
 */
function findSameIngredientMedicine(INPUT, DATA_ARR) {
  let result = [];
  const [INPUT_MEDICINE, INPUT_COUNT] = INPUT.split(' ');

  // 비교할 기준 의약 성분의 각 알파벳 개수를 담아주는 객체
  let alphabetCount = {};
  // 각 알파벳 개수를 세서 넣어줌
  INPUT_MEDICINE.split('').forEach((el) => {
    alphabetCount[el] = alphabetCount[el] + 1 || 1;
  });

  let alphabetCountArr = [];
  let sameAlphabetCount = [];
  for (const DATA of DATA_ARR) {
    let alphabetCountClone = { ...alphabetCount };
    // 데이터로 들어오는 의약 성분들의 각 알파벳 개수를 세서
    // 비교기준 각 알파벳 개수에 더해줌
    DATA.split('').forEach((el) => {
      alphabetCountClone[el] = alphabetCountClone[el] + 1 || 1;
    });

    alphabetCountArr = Object.values(alphabetCountClone);
    // 알파벳의 개수가 2인것들만 filter로 걸러줌
    // 알파벳의 개수가 2인것이 나타내는 의미는 제약 데이터의 성분은 중복이 없으므로
    // 비교기준 성분과 비교대상 성분 둘다 가지는 알파벳이라면
    // 서로 개수를 합쳤을 시 2가 됨
    sameAlphabetCount = alphabetCountArr.filter((el) => el === 2);

    // 개수가 2인 알파벳의 개수가 INPUT_COUNT와 같다면
    // result에 push
    if (sameAlphabetCount.length == INPUT_COUNT) result.push(DATA);
  }

  return result;
}

const INPUT = 'ABCDEFGH 4';
const DATA_ARR = ['EFGHIJKL', 'EFGHIJKM', 'EFGHIJKZ'];

const result = findSameIngredientMedicine(INPUT, DATA_ARR);
console.log(result);