프로그래머스(Level1) - 체육복

지리·2022년 3월 26일
0

알고리즘

목록 보기
6/27

문제

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

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

제한사항

  • 전체 학생의 수는 2명 이상 30명 이하입니다.
  • 체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
  • 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.

입출력 예

nlostreservereturn
5[2,4][1,3,5]5
5[2,4][3]4
3[3][1]2

코드

코드 - 1(reduce)

test 12,13,18 실패...

function solution(n, lost, reserve) {
    var answer = 0;
    
    const afterReserve = lost.reduce((pre,acc)=>{
        let findIndex = reserve.findIndex((r,i)=>{
            if(acc===r||acc===r+1||acc===r-1){
              //조건의 값이 있다면 reserve에서 해당값을 빼준다
            	reserve.splice(i,1);
            	return true
            }
        })
        //조건 값이 있다면 lost값에서 해당값을 빼준다
        return  findIndex>-1 ? pre.filter(p=>p!==acc) : pre
    },lost)
    answer = n-afterReserve.length
    return answer;
}
  • lost의 값과 reserve의 값을 비교하여 값이 같거나, 1차이가 나는 값을 각자 값에서 빼줬다.
  • 처음엔 findIndex말고 filter를 써줬는데 처음 값이 아니라 경우의 값이 다 나오게 되서 처음 하나값만 return하는 findIndex를 사용했다.
  • reduce 잘 써본적은 없는데 조건이 충족하여 값이 빠진 배열을 다시 참조 해야해서 reduce를 사용했다.
  • lost에서 조건의 값을 다 빼줬을 때 나오는 값이 최종적으로 체육복이 없는 사람이기에 (전체 학생수) - (체육복이 없는 학생수)를 해줬다.

이렇게 하니 코드실행할때의 테스트는 제대로 나왔는데, 채점하기 할때 test 12,13,18이 실패로 나왔다...🥲

reduce를 제대로 써본적이 없어서 뭔가 잘못 사용한건가 싶어 다른사람들의 코드를 훝어보니 filter를 이용한 답변들이 많았다. 그래서 다음으로 filter를 이용한 코드를 작성해 보았다.

코드 - 2(filter)

또 다시 test 12,13,18 실패...

function solution(n, lost, reserve) {
    var answer = 0;
    
    const lostStudent = lost.filter(l=>{
        findIndex = reserve.findIndex(r=>r===l||l===r+1||l===r-1)
        if(findIndex>-1){
            reserve.splice(findIndex,1)
            return false
        }else return true
    })
    
    answer = n-lostStudent.length;
   
    return answer;
}
  • filter를 이용하여 lost값에서 reserve속 조건 값을 걸러주는데 앞선 코드와 같이 findIndex를 이용하여 값을 찾고 findIndex가 있을경우(조건 값이 있는경우) false, 없을 경우 true 를 return해 주었다.
  • 결론은 실패...

이쯤되니 정말 뭐가 문제인가 싶었음...😇
왠만하면 내가 답을 맞추기까지는 다른 사람의 코드를 많이 참고안하려 했는데 정말 모르겠어서 검색해보니 체육복 여분이 있는 사람이 잃어버렸을 경우를 먼저 처리해줬어야 했다.

n=5 lost=[3,4] reserve=[2,3]
//자기것 먼저 가져갔을 때 : return 4
//그냥 순서대로 가져갔을 때 : return 5

코드 - 3

test 13,18 실패

function solution(n, lost, reserve) {
    var answer = 0;
  
    let lostButReserve = lost.filter(l=>!reserve.includes(l))
    let reserveButLost = reserve.filter(r=>!lost.includes(r))
    
    const lostStudent = lostButReserve.filter(l=>{
        findIndex = reserveButLost.findIndex(r=>l===r+1||l===r-1)
        if(findIndex>-1){
            reserveButLost.splice(findIndex,1)
            return false
        }else return true
    })
    
    answer = n-lostStudent.length;
   
    return answer;
}

이 문제의 test 13을 검색하니 lost,reserve의 정렬도 return값에 영향을 준다는걸 알게 되었다.

n=5 lost=[4,2] reserve=[3,5]
//정렬 없이 했을 때 : return 4
//정렬을 맞췄을 때 : return 5

오름차순이든 내림차순이든 lost와 reserve이 같으면 된다.

코드 - 최종 🎉

function solution(n, lost, reserve) {
    var answer = 0;

    let lostButReserve = lost.filter(l=>!reserve.includes(l))
    let reserveButLost = reserve.filter(r=>!lost.includes(r))

    lostButReserve.sort((a,b)=>a-b)
    reserveButLost.sort((a,b)=>a-b)

    const lostStudent = lostButReserve.filter(l=>{
        const findIndex = reserveButLost.findIndex(r=>l===r+1||l===r-1)
        if(findIndex>-1){
            reserveButLost.splice(findIndex,1)
            return false
        }else return true
    })

    answer = n-lostStudent.length;
    return answer;
}
profile
공부한것들, 경험한 것들을 기록하려 노력합니다✨

0개의 댓글

관련 채용 정보