조건문을 리스트로 바꾸는 방법?

1. 문제

 

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

 

코딩테스트 연습 - 로또의 최고 순위와 최저 순위

로또 6/45(이하 '로또'로 표기)는 1부터 45까지의 숫자 중 6개를 찍어서 맞히는 대표적인 복권입니다. 아래는 로또의 순위를 정하는 방식입니다. 1 순위 당첨 내용 1 6개 번호가 모두 일치 2 5개 번호

programmers.co.kr

 

로또 6/45(이하 ‘로또’)는 1부터 45까지의 숫자 중 6개를 찍어서 맞히는 대표적인 복권입니다.

 

아래는 로또의 순위를 정하는 방식입니다.

 

그림1. 로또의 순위 정하기

 

로또를 구매한 민우는 당첨 번호 발표일을 학수고대하고 있었습니다.

 

하지만, 민우의 동생이 로또에 낙서를 하여, 일부 번호를 알아볼 수 없게 되었습니다.

 

당첨 번호 발표 후, 민우는 자신이 구매했던 로또로 당첨이 가능했던 최고 순위와 최저 순위를 알아보고 싶어졌습니다.

 

알아볼 수 없는 번호를 0으로 표기하기로 하고, 민우가 구매한 로또 번호 6개가 44, 1, 0, 0, 31, 25라고 가정해보겠습니다.

 

당첨 번호 6개가 31, 10, 45, 1, 6, 19라면, 당첨 가능한 최고 순위와 최저 순위의 한 예는 다음과 같습니다

 

그림2. 민우가 당첨가능한 번호 예시

 

민우가 구매한 로또 번호를 담은 배열 lottos, 당첨 번호를 담은 배열 win_nums가 매개변수로 주어집니다.

 

이때, 당첨 가능한 최고 순위와 최저 순위를 차례대로 배열에 담아 return하도록 solution 함수를 완성해주세요.

 

 

2. 제한사항

 

lottos, win_nums는 길이 6인 정수 배열

 

lottos는 모든 원소가 0 이상 45이하인 정수

 

0은 알아볼 수 없는 숫자

 

0을 제외한 다른 숫자들은 lottos에 2개 이상 담겨있지 않음

 

lottos와 win_nums는 정렬되어 있지 않을 수도 있음

 

win_nums의 원소에는 같은 숫자가 2개 이상 담겨있지 않음

 

 

3. 입출력 예시

 

그림3. 입출력 예시

 

4. 나의 풀이

 

처음엔 lottos와 win_nums를 정렬해야하나 생각했는데 굳이 정렬하지 않아도 됨

 

def solution(lottos, win_nums):
    
    zero_list = []
    
    correct = 0
    
    for num in lottos:
        
        if num == 0:
            
            zero_list.append(num)
            
        else:
            
            if num in win_nums:
                
                correct += 1
                
    max_correct = correct + len(zero_list)
    min_correct = correct

 

lottos에서 하나씩 숫자를 빼서 0인 숫자와 아닌 숫자를 구별함

 

0인 숫자는 따로 list로 빼고 아닌 숫자는 win_nums에 있는지 없는지 비교하여 있으면 맞춘 숫자 수 correct에 1을 더해줌

 

비교과정에서 숫자를 맞추면 win_nums에 들어간 수를 제거해야하나 고민했는데 잘 생각해보면 굳이 제거 안해도 됨

 

제거하면 그만큼 시간이 느려지는거임

 

최대로 맞춘 숫자는 원래 맞춘 숫자의 수에 zero list에 들어간 0의 개수의 합

 

최저로 맞춘 숫자는 원래 맞춘 숫자의 수

 

def rank(correct):
    
    if correct == 6:
        
        rank = 1
    
    elif correct == 5:
    
        rank = 2
        
    elif correct == 4:
        
        rank = 3
        
    elif correct == 3:
    
        rank = 4
        
    elif correct == 2:
    
        rank =5
        
    else:
        
        rank = 6
        
    return rank

 

rank를 if-else를 이용해서 산정하여 최대, 최소 rank를 구함

 

answer = [rank(max_correct), rank(min_correct)]

return answer

 

rank 함수를 이용해서 최대 등수와 최소 등수를 리스트에 담아 return

 

 

5. 다른 풀이

 

if-else로 산정하는게 직관적이긴 한데 그렇게 깔끔하진 않아

 

def solution(lottos, win_nums):
    
    rank = [6,6,5,4,3,2,1]
    
    cnt_0 = lottos.count(0)
    
    ans = 0
    
    for x in win_nums:
        
        if x in lottos:
            
            ans += 1
            
    return rank[cnt_0 + ans], rank[ans]

 

0인 숫자의 개수와 맞춘 숫자의 개수가 중요하다는건 잘 파악을 했는데

 

전체 맞춘 숫자의 수에 따라 rank가 결정되는데 맞춘 숫자의 수를 index로 해서 rank를 list로 만들면

 

if-else없이 바로 가져올수 있다는게 미친 아이디어

 

맞춘 숫자 수가 6개이면 1등이니까 rank[6]=1이 된다는거

 

win_nums에서 숫자 x를 빼서 lottos에 비교하나

 

lottos에서 숫자 x를 빼서 win_nums에 비교하나 잘 생각해보니 큰 상관은 없을듯

 

 

6. 되돌아보기

 

조건문으로 직관적으로 코딩하는것도 좋았지만

 

효율적인 코딩이 중요한 코딩테스트에서

 

리스트와 인덱스를 이용해서 조건문 없이 가져올수 있다는 부분을 기억하면 좋을 것 같다

 

 

TAGS.

Comments