프로그래밍/Algorithm

프로그래머스 체육복 파이썬

모지사바하 2021. 11. 19. 11:10

 

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

 

코딩테스트 연습 - 체육복

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번

programmers.co.kr

 

쉽게 풀었으나 너저분한 코드가 많다. 훨씬 많이 줄일 수 있을듯.

 

풀이:

1. 전체 학생수 에서 체육복을 잃어버린 학생을 뺀 값을 임시로 수업할 수 있는 학생수로 정함

 

2. 1부터 전체 학생 수 만큼 학생 배열 생성

 

3. 체육복을 잃어버림과 동시에 여분을 갖고 있는 학생은 그냥 아무일도 일어나지 않은 학생이므로 체육복을 잃어버린 학생, 여분을 갖고있는 학생에서 빼줌과 동시에 수업할 수 있는 학생 수에 그만큼 더해준다.

 

4. 전체 학생을순회하면서 이전학생 또는 다음 학생이 여분이 있는지 검사하고 있다면 수업할 수 있는 학생 수를 1 증가시키고 체육복을 빌렸으므로 여분 목록에서 제거한다.

 

def solution(n, lost, reserve):
    answer = n - len(lost)
    students = [x for x in range(1, n + 1)]

    remove_student = []
    for l in lost:
        if l in reserve:
            remove_student.append(l)

    answer += len(remove_student)
    for r in remove_student:
        lost.remove(r)
        reserve.remove(r)

    for s in students:
        if s in lost:
            if s - 1 in reserve:
                answer += 1
                reserve.remove(s - 1)
            elif s + 1 in reserve:
                answer += 1
                reserve.remove(s + 1)

    return answer

 

 

 

아래는 다른 사람의 풀이 - 기본적인 방법은 나와 같으나 쓸데없는 코드를 최대한 없앰

 

잃어버린 학생 (lost)과 여분 학생 (reserve) 이 동시에 있는 경우를 제거한 _lost, _reserve 를 새롭게 생성한다. (나의 풀이 3에 해당)

 

여분 학생 을 순회하면서 이전과 이후에 체육복을 잃어버린 학생이 있는지 확인하고 있다면 잃어버린 학생에서 제거한다. (나는 예약을 제거했는데 여기선 잃어버린 학생을 제거)

 

마지막으로 전체 학생수에서 잃어버린 학생수를 빼면 수업할 수 있는 학생수가 나온다 

 

코드가 좀 더 간결하고 세련됐다.

def solution(n, lost, reserve):
    _reserve = [r for r in reserve if r not in lost]
    _lost = [l for l in lost if l not in reserve]
    for r in _reserve:
        f = r - 1
        b = r + 1
        if f in _lost:
            _lost.remove(f)
        elif b in _lost:
            _lost.remove(b)
    return n - len(_lost)