[프로그래머스 1레벨] 체육복

이민선(Jasmine)·2023년 2월 28일
0
post-thumbnail

드디어 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
프로그래머스 1레벨을 다 풀었다 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ (찐으로 감격ㅠㅠㅠㅠㅠㅠㅠㅠㅠ)
1달 넘게 그놈의 체육복 1문제를 남겨두고 1레벨 클리어를 못하고 있었다.
나에게는 그저 마의 체육복 문제였다. 체육복 좀 훔치지마 제발 여분 체육복도 가져오지마

원인을 파악하고 나니 왜 수많은 테케에서 실패했는지 비로소 알게되었다.

문제

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 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명이 체육수업을 들을 수 있습니다.

실패했던 코드

66점 (테케 1,2,3,5,6,9,10,12,24 실패)

function solution(n, lost, reserve) {     
   lost = lost.filter((v) => !reserve.includes(v));
   reserve = reserve.filter((v) => !lost.includes(v));

    let ans = n - lost.length;
    
    lost.sort((a, b) => a - b);
    
    lost.forEach((l)=> {
        if(reserve.includes(l - 1)){
            reserve.splice(reserve.indexOf(l - 1), 1);
            ans++;
        } else if (reserve.includes(l + 1)){
            reserve.splice(reserve.indexOf(l + 1), 1);
            ans++;
        }
    })
    return ans;
}

며칠을 붙잡아봤지만 아무리 생각해도 틀린 구석을 못 찾겠었다.

  • 도난도 당하고 여분도 있는 학생이 있을 경우, 여분이 없지만 도난을 안 당한 학생과 같은 처지이므로 수업을 들을 수 있는 학생으로 취급하면 된다. 따라서 lost와 reserve에서 각각 제외해주었다.
    예컨대 n = [4], lost = [4]일 경우, 이런 예외 처리를 안해주면 4번 학생은 왼쪽에서도 못 빌리고 오른쪽에서도 못빌려서 수업을 못 듣는 학생으로 취급하면 안되기 때문이다.

  • lost가 오름차순으로 정렬되지 않은 테케가 있다고 하길래 lost 오름차순 정렬 예외 처리도 해주었다.
    만약 lost = [4, 2], reserve = [3, 5] 이런 식으로 되어 있다면, lost를 순회하면서 4번 차례 때 reserve에서 3을 없애버리기 때문에 2는 빌릴 곳이 없다. 오름차순 정렬해야 5 -> 4, 3 -> 2 방향으로 대여 가능하다!

이 문제를 어렵게 만드는 주역 중 하나가 예외 케이스들이었다 ㅎㅎㅎ
그래서 이렇게 예외 처리를 하고도 통과를 못한 원인은?

원인 파악

처음에 도난 당했지만 여분이 있는 원소들을 lost와 reserve에서 제거하려고 했는데 이 부분에서 실수가 있었다.
n = 6; lost = [2, 4, 6]; reserve = [1,3,5,6];
으로 예외케이스를 넣고 console.log 찍어보면

   n = 6;lost = [2, 4, 6]; reserve = [1,3,5,6];
   
   lost = lost.filter((v) => !reserve.includes(v));
    console.log(lost);         //[2,4];
   reserve = reserve.filter((v) => !lost.includes(v));  // lost는 새 배열을 의미
    console.log(reserve);     //[1,3,5,6]

reserve에서 중복 제거가 안 되고 있었다. 윗 줄에서 reserve에 포함되지 않는 원소들로 filter했는데, 이를 lost에 재할당했기 때문에 재할당한 lost에 포함되지 않는 reserve 원소들을 걸러내라고 했기 때문이다. 필터링된 lost가 아니라, 필터링되기 전의 lost에 포함되지 않는 reserve 원소들을 걸러내야 한다.
이것도 모르고 !!!! 늦게라도 알아서 다행쓰,,

 n = 6;lost = [2, 4, 6]; reserve = [1,3,5,6];
 
   let lost_noRepeat = lost.filter((v) => !reserve.includes(v));
    console.log(lost_noRepeat);         //[2,4];
   let reserve_noRepeat = reserve.filter((v) => !lost.includes(v)); //lost는 기존 배열을 의미
    console.log(reserve_noRepeat);      //[1,3,5]

lost_noRepeat라는 변수에 별도로 담아 (새로 만들어진 lost가 아니라) 기존 lost에 포함되지 않는 원소들을 추출할 수 있도록 처리하였다.

통과 코드

function solution(n, lost, reserve) {     
   let lost_noRepeat = lost.filter((v) => !reserve.includes(v));
   let reserve_noRepeat = reserve.filter((v) => !lost.includes(v));

    let ans = n - lost_noRepeat.length;
    
    lost_noRepeat.sort((a, b) => a - b);
    
    lost_noRepeat.forEach((l)=> {
        if(reserve_noRepeat.includes(l - 1)){
            reserve_noRepeat.splice(reserve_noRepeat.indexOf(l - 1), 1);
            ans++;
        } else if (reserve_noRepeat.includes(l + 1)){
            reserve_noRepeat.splice(reserve_noRepeat.indexOf(l + 1), 1);
            ans++;
        }
    })
    return ans;
}

우여곡절 끝에 통과!!!!

이런 사진은 처음 올려본다. 그만큼 감격했다는 뜻 ㅜ

이렇게 나의 우여곡절 party 끝에 1레벨을 모두 통과했다!!
이제 남은 2레벨 친구들이 나를 기다리고 있다. 어렵지만 빡시게 공부해서 모두 통과하자!

자스민 화이팅!!

참고:
https://velog.io/@euneun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B2%B4%EC%9C%A1%EB%B3%B5-%EA%B7%B8%EB%A6%AC%EB%94%94-javascript

profile
기록에 진심인 개발자 🌿

0개의 댓글