위의 문제에서 요점은
체육시간에 체육복을 몇명이나 입을 수 있는가? 입니다.
그렇다면 입을 수 있는 경우는? 이 학교는 체육복을 가져오는게 기본값으로 되어있는 학교기 때문에, 누가 안 훔쳐갔으면 입습니다.
가장 기본적인 공식은 전체에서 도난당한 불쌍한 녀석들(lost
)을 빼주는 n - lost.length
로 구할 수 있습니다.
여기서 한가지 변수가 더 추가되는데, 그게 바로 훔쳐서 한 벌이 더 있는지 아니면 도난당해서 한벌 더 샀는데 체육복을 찾았는지 모를 여벌을 가져온 학생들(reserve) 입니다.
여벌을 가져온 학생들은 자신의 앞 혹은 뒷 번호의 학생에게 체육복을 빌려줄 수 있습니다.
웃긴건 도난당한 학생 목록(lost)과 여벌을 가져온 학생 목록(reserve)에 동시에 존재할 수도 있다는 것입니다.
그런 경우에는 한개 도난당했으니까 자기꺼 입는 거로 쳐서 누구한테 빌려줄 수 없습니다.
그럼 결국에는 두 곳에 동시에 존재하면 걔는 여벌 없이 자기꺼 입는 거랑 같으니 아예 고려하지 말아야 합니다.
결국
그래서 제 정답은 아래와 같습니다.
function solution(n, lost, reserve) {
let answer = n;
// 두 배열에 중복으로 존재하는 학생 고려 안함
lost.map((stdNum) => {
if(reserve.includes(stdNum)){
lost = lost.filter((lostStdNum) => stdNum !== lostStdNum);
reserve = reserve.filter((reserveStdNum) => stdNum !== reserveStdNum);
}
});
// 앞부터 확인해서 여분 가져온 학생 있으면 빌리기
lost.map((stdNum) => {
let beforeStdNum = stdNum - 1;
let afterStdNum = stdNum + 1;
if(reserve.includes(beforeStdNum)){
lost = lost.filter((lostStdNum) => stdNum !== lostStdNum);
reserve = reserve.filter((reserveStdNum) => beforeStdNum !== reserveStdNum);
}else if(reserve.includes(afterStdNum)){
lost = lost.filter((lostStdNum) => stdNum !== lostStdNum);
reserve = reserve.filter((reserveStdNum) => afterStdNum !== reserveStdNum);
}
});
return answer - lost.length;
}
자바스크립트 배열 메소드 map
수행 도중에 원본을 splice
하는 등의 원본 손상 행위를 하면, map
메소드가 올바르게 수행되지 않습니다. 주의하여야 합니다.
splice
를 이용하여 원본 배열을 지울 때는 arr.splice(arr.indexOf(value), 1)
의 코드로 삭제 가능합니다.
filter
를 이용해 값을 대체하는 방식은 원본 레퍼런스를 훼손하지 않기 때문에 map
동작도 방해하지 않습니다.