코딩 테스트 연습/[프로그래머스] Python

[LV.3] 로또의 최고 순위와 최저 순위

duswjd_data 2025. 8. 12. 09:50

문제

https://school.programmers.co.kr/learn/courses/30/lessons/77484

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


문제 설명

  • 로또 번호 6개를 샀는데, 동생이 낙서를 해서 일부 숫자가 지워짐 → 0으로 표시됨
  • 민우는 자신의 로또 번호로 최고 몇 등, 최저 몇 등에 당첨될 수 있는지 알고 싶어 함

  • 제한사항
    • lottos는 길이 6인 정수 배열
    • lottos의 모든 원소는 0 이상 45 이하인 정수
      • 0은 알아볼 수 없는 숫자를 의미
      • 0을 제외한 다른 숫자들은 lottos에 2개 이상 담겨있지 않음
      • lottos의 원소들은 정렬되어 있지 않을 수도 있음
    • win_nums은 길이 6인 정수 배열
    • win_nums의 모든 원소는 1 이상 45 이하인 정수
      • win_nums에는 같은 숫자가 2개 이상 담겨있지 않음
      • win_nums의 원소들은 정렬되어 있지 않을 수도 있음

정답 코드

def solution(lottos, win_nums):
    match_count = len(set(lottos) & set(win_nums))  # 확실히 맞춘 숫자 개수
    zero_count = lottos.count(0)                    # 모르는 숫자 개수

    def get_rank(count):
        return 7 - count if count >= 2 else 6       # 순위 계산

    best_rank = get_rank(match_count + zero_count)
    worst_rank = get_rank(match_count)

    return [best_rank, worst_rank]

코드 설명

def solution(lottos, win_nums):

 

  • lottos: 민우가 구매한 로또 번호 리스트 (길이 6, 일부 번호는 0으로 표시)
  • win_nums: 이번 회차의 당첨 번호 리스트 (길이 6)
    match_count = len(set(lottos) & set(win_nums))

 

  • lottos와 win_nums의 교집합을 계산하여, 실제로 맞은 번호 개수 구하기
  • 중복은 없다는 전제가 있으므로 set을 사용해도 문제 없음
  • 0은 자동으로 제외됨 (win_nums에는 0이 없기 때문)

 

    zero_count = lottos.count(0)

 

  • 알아볼 수 없는 번호(0)의 개수 세기
  • 최고 순위 계산 시, 이 0들은 당첨 번호 중 아직 포함되지 않은 어떤 숫자와도 매치될 수 있다고 가정
    def get_rank(count):
        return 7 - count if count >= 2 else 6

 

  • 번호를 몇 개 맞췄는지(count)에 따라 순위를 반환하는 함수
  • 규칙:
    • 6개 맞춤 → 1등 → 7 - 6 = 1
    • 5개 맞춤 → 2등 → 7 - 5 = 2
    • ...
    • 1개 이하 맞춤 → 6등 (낙첨)
    best_rank = get_rank(match_count + zero_count)
    worst_rank = get_rank(match_count)

 

 

  • 최고 순위: 현재 맞춘 개수 + 0이 전부 맞는 번호일 때
  • 최저 순위: 0이 모두 틀린 번호일 때
    return [best_rank, worst_rank]

 

  • [최고 순위, 최저 순위] 리스트로 반환

첫 번째 시도 (실패)

def solution(lottos, win_nums):
    answer = []
    cnt = 0
    zero_cnt = 0
    
    win_nums_set = set(win_nums)
    for i in lottos:
        if i in win_nums_set:
            cnt += 1
    
    if lottos.count(0) == len(lottos):
        cnt = 1
        zero_cnt = lottos.count(0) - 1
    else:
        zero_cnt = lottos.count(0)
    
    answer.append(cnt)
    answer.append(cnt + zero_cnt)
    
    return answer

틀린 이유

 

  • 순위 변환 로직이 없음
    • cnt와 zero_cnt를 센 후, 그것을 당첨 순위로 변환하지 않음 → 당첨 순위를 구해야되는거 잊지 말기
  • cnt = 1, zero_cnt = lottos.count(0) - 1 등은 의미가 불명확하고 불필요

두 번째 시도 (실패 → 정확성: 93.3)

def solution(lottos, win_nums):
    answer = []
    cnt = 0
    
    win_nums_set = set(win_nums)
    for i in lottos:
        if i in win_nums_set:
            cnt += 1
    
    answer.append(7 - (cnt + lottos.count(0)))
    
    if lottos.count(0) == len(lottos):
        answer.append(6)
    else:
        answer.append(7 - cnt)
    
    return answer

 


틀린 이유

if lottos.count(0) == len(lottos):
    answer.append(6)
  • 전부 0이면 무조건 6등이라고 가정한 코드
  • 항상 최고/최저 순위를 정확하게 계산할 수 있기 때문에 '모든 숫자가 0일 때만' 예외 처리하는 조건은 의미가 없음