본문 바로가기
Algorithm/Programmers

[Programmers] 체육복(JavaScript)

by 백승전 2022. 8. 4.

 

알림

 

본 포스팅은 공부 목적으로 작성된 글이며 상업적 목적으로 절대 사용되지 않았음을 밝힙니다.

 

문제

 

https://school.programmers.co.kr/learn/courses/30/lessons/42862

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.

전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.

 

코드

 

function solution(n, lost, reserve) {
    // 정답 = 전체 학생 수 - 도난 당한 학생 수
    let answer = n - lost.length;
    // 도난 당한 학생들 필터링
    let newLost = lost.filter((e) => {return !reserve.includes(e)});
    // 여분 있는 학생들 필터링
    let newReserve = reserve.filter((e) => {return !lost.includes(e)});
    // 빌려줄 순 없지만 수업 참여는 가능하니 answer++
    answer += lost.length - newLost.length;
    
    // 도난 당한 학생 오름차순
    newLost.sort((a, b) => {return a - b});
    
    newLost.map((e) => {
        if(newReserve.includes(e - 1)){ // 여분 학생이 왼쪽 위치 시
            // 빌려주고 필터링(그리고 answer++)
            newReserve = newReserve.filter((value) => {return value !== e - 1})
            answer++;
        }else if(newReserve.includes(e + 1)){ // 여분 학생이 오른쪽 위치 시
            // 빌려주고 필터링(그리고 answer++)
            newReserve = newReserve.filter((value) => {return value !== e + 1})
            answer++;
        }
    })
    
    return answer;
}

 

풀이

 

결론적으로 체육 수업은 전체 학생 수 중에서, 체육복이 있는 학생들만 수업에 참여할 수 있기 때문에, 전체 학생 수에서 도난 당한 학생 수를 뺀 뒤 리턴해주면 됩니다.

 

하지만 여기서 여러가지 경우의 수를 생각해야 하는데요.

첫 번째로, 여분으로 가지고 있는 학생들이 빌려줄 수 있다는 것.

두 번째로, 여분으로 가지고 있는 학생들도 도난 당해서 빌려줄 수 없다는 것.

세 번째로, 두 번째와 마찬가지로, 도난 당한 무리에 여분이 있는 학생이 있을 수 있어, 정말 도난 당한 애들만 남겨놔야 하는 것입니다.

 

첫 번째의 경우 조건문을 통해, 여분이 있는 학생이 왼쪽 혹은 오른쪽에 위치했는지를 판단 후, 빌려주고 정답에 더해주면 됩니다.

 

두 번째의 경우 여분이 있는 학생들의 배열에서 도난 당한 학생들 배열에 포함되지 않은, 정말 빌려줄 수 있는 학생들로만 배열을 다시 반환해주면 되고,

 

세 번째의 경우에도 도난 당했지만 여분이 있는 학생을 제외, 정말 잃어버린 학생들로만 배열을 다시 반환해줍니다.

 

여기서 map 함수를 실행시키기 전에, 도난 당한 학생들 중에서, 여분이 있어서 필터링 된 학생들의 수만큼 정답에 더해줘야 하는데요. 왜냐하면 이 학생들은 빌려줄 순 없으니 필터링이 되었지만, 수업에 참여는 가능하기 때문입니다.

 

마지막으로, map 함수 내 조건문을 통해 첫 번째에서 말한 대로 정답을 리턴해주는 과정을 거치면 됩니다.

 

하지만 여기서 한 가지 과정을 더 거쳐야 하는데요. 바로 도난 당한 학생들을 오름차순 하는 과정입니다.

왜냐하면 5명의 학생 중, 도난 당한 학생들이 [2, 4]이고, 빌려줄 수 있는 학생들은 [3, 5]일 경우, 원래대로라면 3번은 2번에게, 5번은 4번에게 체육복을 빌려줘 5명 전부가 수업에 참여할 수 있을 것인데요.

오름차순 없이 [4, 2]로 받아올 경우, 3번은 4번에게 빌려줄 수 있지만, 5번은 2번에게 빌려줄 수 없기 때문에 4명밖에 수업에 참여할 수 없기 때문입니다.

댓글