본문 바로가기
👩‍💻 Programming/Coding Test 문제 풀이

[Programmers] level 1: 체육복 by JavaScript

by codingBear 2022. 7. 6.
728x90
반응형

 이번 글은 다음 링크의 글들을 참고하여 작성하였습니다.

 

 

[프로그래머스] 체육복 | JavaScript

탐욕 알고리즘(greedy algorithm) 탐욕 알고리즘은 최적해를 구하는 데에 사용되는 근사적인 방법으로, 여러 경우 중 하나를 결정해야 할 때마다 그 순간에 최적이라고 생각되는 것을 선택해 나가는

onlydev.tistory.com

 

[프로그래머스] 체육복 JavaScript

풀이 function solution(n, lost, reserve) { // 모든 student가 체육복을 1개씩 갖고 있는 것으로 가정한 배열. var students = new Array(n).fill(1); // 체육복을 잃어버린 student의 체육복 개수를 -1 감소 lo..

seomoon.tech

 

[프로그래머스] level1. 체육복 ( javascript)

문제 점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로

zzemal.tistory.com


 이번 문제에 대한 자세한 사항은 다음 링크를 참조하길 바란다.

 

 이번 문제 역시 제약조건을 꼼꼼히 읽어야 풀 수 있는 문제이다. 유의해서 봐야 할 부분은 '여벌 체육복을 가져온 학생도 체육복 한 벌을 도난 당할 수 있다'라는 부분인데 이 경우 해당 학생을 체육복 한 벌만 가진 학생으로 처리해줘야 한다. 이 점을 고려하지 않으면 테스트 케이스에서 실패가 계속해서 뜰 것이다.

 내가 작성한 코드의 경우 값은 제대로 나오나 제약 조건을 충족하지 못해 모든 테스트 케이스를 통과하지 못했다. 따라서 다른 사람들의 코드를 참고하여 문제를 풀었다.

 

Solutions

Solution 1.
/* My Solution */
function solution(n, lost, reserve) {
  let answer = n - lost.length
  lost = lost.filter(l => !reserve.includes(l)).sort((a, b) => a - b)
  reserve = reserve.filter(r => !lost.includes(r)).sort((a, b) => a - b)
  for (let i = 0 ; i < reserve.length; i++) {
      for (let j = 0 ; j < lost.length; j++) {
          if (reserve[i] === lost[j] - 1 || reserve[i] === lost[j] + 1) {
              reserve.splice(i, i+1)
              lost.splice(j, j+1)
              answer++
          }
      }
  }
  return answer
}
Solution 2.
/* Filter Ver. */
function solution(n, lost, reserve) {
  // 여별 체육복을 가진 학생과 체육복을 도난 당한 학생 모두에 속하는 사람을 제외
  const realLost = lost
    .filter((l) => !reserve.includes(l))
    .sort((a, b) => a - b);
  let realReserve = reserve
    .filter((r) => !lost.includes(r))
    .sort((a, b) => a - b);
  // 체육 수업을 들을 수 있는 학생 수 = 전체 학생 수 - 체육복 없는 학생 중 체육복을 빌리지 못하는 학생 수
  return (
    n -
    realLost.filter((l) => {
      // 여별 체육복을 가진 학생 중 도난 당한 학생과 체격 차이가 1인 학생
      const lendStudent = realReserve.find((r) => {
        return Math.abs(l - r) === 1;
      });
      // 빌려주는 학생과 빌리는 학생의 체격 차이가 1이 아닌 경우 그대로 realLost에 남김
      if (!lendStudent) return true;
      // 여벌 체육복은 한 학생에게만 빌려줄 수 있으므로 이미 체육복을 빌려준 학생은 다음 계산에서는 제외
      realReserve = realReserve.filter((r) => r !== lendStudent);
    }).length
  );
}
Solution 3.
/* New Array Ver. */
function solution(n, lost, reserve) {
    // 모든 학생이 체육복을 1개씩 갖고 있다고 가정
  let students = new Array(n).fill(1);
  // 체육복을 잃어버린 학생의 체육복 개수를 --
  lost.forEach((l) => students[l - 1]--);
  // 체육복 여벌이 있는 학생의 체육복 개수 ++
  reserve.forEach((r) => students[r - 1]++);
  // students 배열을 순회하면서 여분 체육복이 있는 학생이 체육복이 없는 앞, 뒤의 학생에게 자신의 체육복을 나눠준다. 이때 앞 -> 뒤로 순회하기 때문에 앞에 있는 학생부터 나눠준다.
  students.forEach((_, i, arr) => {
    if (arr[i] > 1 && arr[i - 1] === 0) {
      arr[i]--;
      arr[i - 1]++;
    } else if (arr[i] > 1 && arr[i + 1] === 0) {
      arr[i]--;
      arr[i + 1]++;
    }
  });
  return students.filter((v) => v > 0).length;
  );
}
Solution 4.
function solution(n, lost, reserve) {
  let answer = n - lost.length;
  let realLost = lost.filter((l) => !reserve.includes(l)).sort((a, b) => a - b);
  let realReserve = reserve
    .filter((r) => !lost.includes(r))
    .sort((a, b) => a - b);
  // 체육 수업 들을 수 있는 학생 수 = 전체 학생 수 - 체육복 갖고 있지 않은 학생 수
  answer += lost.length - realLost.length;
  // 여벌의 체육복을 가진 학생 중 체육복을 도난 당한 학생이 있다면 realReserve 배열에서 제외하고 answer ++
  realLost.forEach((l) => {
    if (realReserve.length === 0) return;
    if (realReserve.includes(l - 1)) {
      realReserve = realReserve.filter((r) => r !== l - 1);
      answer++;
    } else if (realReserve.includes(l + 1)) {
      realReserve = realReserve.filter((r) => r !== l + 1);
      answer++;
    }
  });
}
728x90
반응형

댓글