[Python] 프로그래머스 Level 1 체육복

지애·2024년 6월 25일
1

코딩테스트

목록 보기
6/12

생각의 흐름

  • 일단 번호 순서대로 정렬
  • 여벌 체육복을 가져왔지만 도난도 당해버린 케이스를 먼저 고려

    lost와 reserve에서 해당 케이스의 학생을 모두 제외한다

  • 그러고 나서, 도난당한 학생은 맨 첫번호와 끝번호를 제외하고 (인덱스가 아니기 때문에 상관 X) 모두 자신보다 작은 사이즈의 친구에게 체육복을 빌리도록 함. 바로 앞번호가 빌려줄 수 없다면 바로 뒷번호에게 요청.
  • 이렇게 하면 최대한 많은 사람이 체육시간에 나갈 수 있게 될 줄 알았다...

처음 작성한 코드

  • 조금 더러워 보여도... 입력값이 크지 않으니까 제대로만 로직을 설계했다면 상관 없을 것이라고 생각했다...그런데 반 이상의 테케를 통과하지 못하는 사태 발생...!🥺
# 여벌 체육복은 하나만 가져올 수 있다고 가정
# 여벌 체육복을 가져온 학생도 도난 당할 수 있음
def solution(n, lost, reserve):
    lost.sort()
    reserve.sort()
    # 여벌 체육복을 가져온 학생이 도난 당한 경우 고려 (자기 자신에게 빌려간다고 생각)
    for l in lost:
        if l in reserve:
            lost.remove(l)
            reserve.remove(l)

    for l in lost:    
        if l != 1 and l != n:
            if l-1 in reserve:
                lost.remove(l)
                reserve.remove(l-1)
            elif l+1 in reserve:
                lost.remove(l)
                reserve.remove(l+1)
                
        if l == 1:
            if l+1 in reserve:
                lost.remove(l)
                reserve.remove(l+1)
                
        if l == n:
            if l-1 in reserve:
                lost.remove(l)
                reserve.remove(l-1)
                

    answer = n - len(lost)
    return answer

입력값 〉 5, [2, 4], [1, 3, 5] 일 때 자꾸 answer가 4가 나옴.....왜?

재도전

# 여벌 체육복은 하나만 가져올 수 있다고 가정
# 여벌 체육복을 가져온 학생도 도난 당할 수 있음
def solution(n, lost, reserve):
    lost.sort()
    # 여벌 체육복을 가져온 학생이 도난 당한 경우 고려 (자기 자신에게 빌려간다고 생각)
    for l in lost:
        if l in reserve:
            lost.remove(l)
            reserve.remove(l)

# 인덱스가 아니니까 1,n의 경우 고려하지 않아도됨!!
    for l in lost:
        f = l-1
        b = l+1
        
        if f in reserve:
            lost.remove(l)
            reserve.remove(f)

        elif b in reserve:
            lost.remove(l)
            reserve.remove(b)
        

    answer = n - len(lost)
    return answer
  • 또 실패...
  • lost를 for 문으로 순회하는 과정에서 lost를 삭제해서 그런가???
    -> 그렇다. for문에서 순회하고 있는 list를 for문 안에서 마음대로 변경해서 발생한 문제...

최종 코드

# 여벌 체육복을 가져온 학생도 도난 당할 수 있음
def solution(n, lost, reserve):
    
    # 여벌 체육복을 가져온 학생이 도난 당한 경우 고려 (자기 자신에게 빌려간다고 생각)
    total_lost = list(set(lost)-set(reserve))
    total_reserve = list(set(reserve)-set(lost))
    total_lost.sort()
    
    # 인덱스가 아니니까 1,n의 경우 고려하지 않아도됨!!
    # 순회를 위한 _lost
    _lost = total_lost.copy()
    for l in _lost:
        f = l-1
        b = l+1
        
        if f in total_reserve:
            total_lost.remove(l)
            total_reserve.remove(f)

        elif b in total_reserve:
            total_lost.remove(l)
            total_reserve.remove(b)
        

    answer = n - len(total_lost)
    return answer

회고

  • 아이디어는 적절했으나, 코드 구현에 문제가 있었다. 쉽다고 방심하지 말자! for문에서 list 구조 변경이 필요할 땐 깊은 복사를 통해 새로운 list를 만들어서 사용하자
profile
차근차근

0개의 댓글