문제 설명
점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.
전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요
제한사항
- 전체 학생의 수는 2명 이상 30명 이하입니다.
- 체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
- 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
- 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
- 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.
입출력 예
n | lost | reserve | return |
5 | [2, 4] | [1, 3, 5] | 5 |
5 | [2, 4] | [3] | 4 |
3 | [3] | [1] | 2 |
입출력 예 설명
예제 #1
1번 학생이 2번 학생에게 체육복을 빌려주고, 3번 학생이나 5번 학생이 4번 학생에게 체육복을 빌려주면 학생 5명이 체육수업을 들을 수 있습니다.
예제 #2
3번 학생이 2번 학생이나 4번 학생에게 체육복을 빌려주면 학생 4명이 체육수업을 들을 수 있습니다.
※ 공지 - 2019년 2월 18일 지문이 리뉴얼되었습니다.
※ 공지 - 2019년 2월 27일, 28일 테스트케이스가 추가되었습니다.
※ 공지 - 2021년 7월 28일 테스트케이스가 추가되었습니다.
※ 공지 - 2021년 8월 30일 테스트케이스가 추가되었습니다.
문제 풀이 시도 1 - 실패
- 내가 접근했던 방식으로 풀었을 떄 정확도 75점이 나왔고, 계속 틀리는 테스트 경우가 발생했다.
- 내가 접근했던 방식은 아래와 같다.
answer = 전체인원 - 도둑맞은 학생 수 + 여분을 가지고 있는 학생 수 - 도둑맞은 학생 중 여분을 가지고 있던 수
내가 작성한 식은 아래 논리로 작성했다.
1) 전체인원에서 도둑맞은 학생을 뺀다.
2) "여분 옷을 가진 학생 수"에서 "여분 옷을 가진 학생 중 옷을 도둑맞은 학생 수"를 뺀 수를 1)에 더한다.
- 내가 접근했던 방식은 틀렸는데, 아래의 경우를 생각하지 못했다
예) n=5 , lost = [1], reserve=[1] 인 경우
1번 학생은 여분의 옷을 가지고 있었으므로, 누구에게 옷을 빌릴 필요가 없다. 그래서 5명이 나갈 수 있다.
문제 풀이 시도 2 - 실패
let needClothes = lost.filter((v) => !reserve.includes(v));
let hasExtra = reserve.filter((v) => !lost.includes(v));
console.log(needClothes);
console.log(hasExtra);
console.log(needClothes === []);
console.log("compare", hasExtra.length > needClothes.length);
console.log("answer", 5 - needClothes.length + hasExtra.length);
if (needClothes === []) answer = n;
else {
if (hasExtra.length >= needClothes.length) answer = n;
else answer = n - needClothes.length + hasExtra.length;
};
1. 옷이 필요한 사람들, 여분의 옷이 있는 사람을 구한다.
2. answer 에 아래의 경우로 나누어 값을 할당한다.
1) 옷이 필요한 사람이 없는 경우는 answer 에 전체 인원(n)을 할당
2) 여분의 옷이 있는 사람이 옷이 필요한 사람 수 이상인 경우 answer 에 전체 인원(n)을 할당
3) 옷이 필요한 사람이 여분 옷을 가지고 있는 사람보다 많은 경우, 전체인원에서 옷이 필요한 인원을 빼고 여분의 옷이 있는 인원을 더한 값을 answer 에 할당
이 방식은 틀렸는데, 문제에 제시된 아래의 조건을 생각하지 못하여, lost 와 reserve 배열을 정렬하지 못했다.
학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다.
문제 풀이 시도 3 - 성공
function solution(n, lost, reserve) {
var answer = 0;
let needClothes = lost.sort((a,b) => a-b).filter((v) => !reserve.includes(v));
let hasExtra = reserve.sort((a,b) => a-b).filter((v) => !lost.includes(v));
const noClothes = needClothes.filter((noClothes) => {
// 빌려줄 수 있는 첫번째 학생 있는지 확인
// 있으면 학생 번호, 없으면 undefined 할당됨
let rent = hasExtra.find((extra) => Math.abs(extra - noClothes) == 1);
// 체육복 빌려줄 사람이 없으면 그대로 lost 리턴
if(!rent) return noClothes;
// 빌려준 사람 제외하기
hasExtra = hasExtra.filter((extra) => extra !== rent);
})
answer = n - noClothes.length;
return answer;
}
1. lost, reserve 를 오름차순으로 정렬하고 옷이 필요한 사람, 여분의 옷을 가지고 있는 사람 배열을 구한다.
2. 빌려줄 수 있는 학생을 찾고, 빌릴 수 없는 학생들의 배열 noClothes 을 구한다.
3. 전체 인원에서 빌릴 수 없는 학생들의 수를 뺀 값을 answer 에 할당하고, 그 값을 출력한다.
문제를 통해 공부한 것 (Ref : MDN)
1. array.prototype.find()
find() 메서드는 주어진 판별 함수를 만족하는 첫 번째 요소의 값을 반환한다. 그런 요소가 없다면 undefined를 반환한다.
2. Math.abs()
Math.abs() 함수는 주어진 숫자의 절대값을 반환한다. x가 양수이거나 0이라면 x를 리턴하고, x가 음수라면 x의 반대값, 즉 양수를 반환한다.
빈 객체, 하나 이상의 요소를 가진 배열, 숫자가 아닌 문자열, undefined나 빈 매개변수를 받으면 NaN을 반환한다. null, 빈 문자열이나 빈 배열을 제공하면 0을 반환한다.
Math.abs('-1'); // 1
Math.abs(-2); // 2
Math.abs(null); // 0
Math.abs(''); // 0
Math.abs([]); // 0
Math.abs([2]); // 2
Math.abs([1,2]); // NaN
Math.abs({}); // NaN
Math.abs('string'); // NaN
Math.abs(); // NaN
3. array.prototype.filter()
배열 내 각 요소에 대해 한 번 제공된 callback 함수를 호출해, callback이 true로 강제하는 값을 반환하는 모든 값이 있는 새로운 배열을 생성한다. 이 때, 따로 거짓 같은 값으로 정의된 값이 아니면 모두 참 같은 값으로 평가된다. (예: false, 0, -0, 0n, "", null, undefined와 NaN 등)
4. 참 같은 값, 거짓 같은 값
JavaScript는 if 문과 같이 부울 값이 필요한 경우를 만나게 되면 자동으로 형 변환을 한다.
이러한 이유로 인해 우리는 가끔 부울 타입으로 변환되었을 때, true와 false이 됨을 의미하는 값들을 각각 "참 값"과 "거짓 값"으로 부른다. 또는 각각 "참 같은 값(truthy)"와 "거짓 같은 값(falsy)"라는 식으로 부른다.
'코딩 테스트 Coding Test > 프로그래머스 Programmers' 카테고리의 다른 글
[프로그래머스] 비밀지도 - 자바스크립트 (0) | 2022.07.27 |
---|---|
[프로그래머스] 모의고사 - 자바스크립트 (0) | 2022.07.26 |
[프로그래머스] 실패율 - 자바스크립트 (0) | 2022.06.29 |
[프로그래머스] 소수 찾기 - 자바스크립트 (0) | 2022.06.29 |
[프로그래머스] 나머지가 1이 되는 수 - 자바스크립트 (0) | 2022.06.27 |
댓글