[프로그래머스] 체육복

Changyun Go·2021년 8월 24일
0

프로그래머스 Level 1

목록 보기
13/19
post-thumbnail

체육복

문제 설명


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

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

제한 사항


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

나의 풀이


function solution(n, old_lost, old_reserve) {
    let answer = 0;
    let lost = old_lost.filter(x => !old_reserve.includes(x));
    let reserve = old_reserve.filter(x => !old_lost.includes(x));
    
    lost.sort((a, b) => a - b);
    reserve.sort((a, b) => a - b);
    
    for(let i = 0; i < lost.length; i++){
        for(let j = 0; j < reserve.length; j++){
            if(lost[i] + 1 === reserve[j] || lost[i] - 1 === reserve[j]){
                lost.splice(i, 1);
                reserve.splice(j, 1); 
                i--;
                j--;
            }
        }
    }
    answer = n - lost.length;
    return answer;
}

다른 사람의 풀이


function solution(n, lost, reserve) {
    let tmp = reserve.slice()

    for (let i in tmp) {
      let key = lost.indexOf(tmp[i])

      if (key != -1) {
        lost.splice(key, 1);
        reserve.splice(reserve.indexOf(tmp[i]), 1);
      }
    }

    for (let i of reserve) {
      let key = lost.includes(i-1) ? lost.indexOf(i-1) : lost.indexOf(i+1)

      if (key != -1) {
        lost.splice(key, 1)
      }
    }

    return n - lost.length
  }

P.S.

이번 문제는 제한 사항이 많아서 코드가 정답까지 이어지는 데 시간이 꽤 걸렸다😅

나는 filter를 이용해서 lost와 reserve의 중복된 요소를 제거하고, 오름차순으로 정렬하여 반복문 내에서 lost보다 1만큼 크거나 작은 요소를 찾으면 해당되는 lost와 reserve를 splice를 통해 제거했다. 그리고 splice로 인해 당겨진 배열을 정상적으로 읽기 위해서 반복문의 카운터 변수를 하나씩 감소시켰다.

다른 사람의 풀이를 보면
1. slice를 이용해 reserve를 tmp라는 변수에 그대로 복사했다.
2. tmp에 중복되는 lost 요소의 인덱스를 찾아 key라는 변수에 대입하고, 값이 없으면 해당되는 lost 요소와 reserve 요소를 splice를 통해 제거했다.
3. reserve 요소가 lost 요소보다 1만큼 크거나 작은 경우, 해당 lost 요소의 인덱스를 구해서 key에 넣어주고 마찬가지로 값이 있으면 요소를 제거하여 최종적인 lost 배열의 길이를 구했다.

배열의 요소만을 활용하지 않고 index로 조건을 작성하고, slice를 이용해 배열을 복사하여 사용하는 것이 인상적이었다.

오름차순으로 정렬하지 않고 어떻게 문제가 해결됐는지 찾아보다가, 순서를 보장하지 않는 특성을 가진 for...in이 개체의 특성에 의해 오름차순으로 정렬해버리는 성질이 있다는 것을 알게 되었다. 그리고 이렇게 속성에 의존하는 것은 나쁜 스타일이라는 것도 알았다😉

0개의 댓글