라떼는말이야

[프로그래머스 lv1] 모의고사 (파이썬) 본문

알고리즘/코딩 테스트

[프로그래머스 lv1] 모의고사 (파이썬)

MangBaam 2021. 6. 17. 20:37
반응형

문제 설명

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다.

1번 수포자가 찍는 방식: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
2번 수포자가 찍는 방식: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ...
3번 수포자가 찍는 방식: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...

1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution 함수를 작성해주세요.

제한조건

- 시험은 최대 10,000 문제로 구성되어있습니다.
- 문제의 정답은 1, 2, 3, 4, 5중 하나입니다.
- 가장 높은 점수를 받은 사람이 여럿일 경우, return하는 값을 오름차순 정렬해주세요.

입출력 예

입출력 예

입출력 예 설명

입출력 예 #1
  - 수포자 1은 모든 문제를 맞혔습니다.
  - 수포자 2는 모든 문제를 틀렸습니다.
  - 수포자 3은 모든 문제를 틀렸습니다.
따라서 가장 문제를 많이 맞힌 사람은 수포자 1입니다.

입출력 예 #2
  - 모든 사람이 2문제씩을 맞췄습니다.

난이도가 높지 않은 문제이다.

관건은 어떻게 정답 처리를 할 것인지, 순위를 어떻게 매길 것인지가 되겠다.

 

 

 

나는 정답이 들어있는 answers 리스트를 순회하며 한 문제당 3명의 수포자를 채점했다.

이때 사용한 것이 for ~ in enumerate 이다.

그냥 for in 리스트 를 하면 리스트만 순회하지만 enumerate를 하면 인덱스도 확인할 수 있다.

collect = [0] * 3

for i, ans in enumerate(answers):
        # 1번 수포자
        # 1 2 3 4 5 ...
        a1 = i % 5 + 1
        if ans == a1:
            collect[0] += 1
        
        # 2번 수포자
        # 2 1 / 2 3 / 2 4 / 2 5 ...
        mat2 = [2, 1, 2, 3, 2, 4, 2, 5]
        a2 = i % 8
        if ans == mat2[a2]:
            collect[1] += 1
                
        # 3번 수포자
        # 3 3 / 1 1 / 2 2 / 4 4 / 5 5 ...
        mat3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
        a3 = i % 10
        if ans == mat3[a3]:
            collect[2] += 1

위와 같이 answers를 순회하며 i와 ans를 받을 수 있다. 여기서 i는 0, 1, 2, ... 인덱스이며, ans가 원래 for문을 돌리면 얻을 수 있는 그 값이다.

1번 수포자의 경우 1, 2, 3, 4, 5의 패턴으로 반복되기 때문에 단순히 i % 5 를 해서 1을 더해주면 된다.

 

2번 수포자의 경우 2, 1, 2, 3, 2, 4, 2, 5의 패턴으로 반복되기 때문에 처음에는 2가 나오는 홀수 번째 값과 1, 3, 4, 5가 반복적으로 나오는 짝수 번째 값을 따로 처리할까 하다가 반복되는 패턴의 길이가 길지 않아서 그냥 다 집어넣었다.

 

3번 수포자의 경우도 마찬가지로 3, 1, 2, 4, 5로 입력 후 두 번씩 반복하도록 처리할 까 하다가 그냥 다 때려 넣었다.

 

오히려 계산하는 부분이 훨씬 간단해져서 직관적으로나 시스템적으로나 더 좋아졌다.

 

collect 리스트는 3명의 수포자가 정답을 맞춘 횟수를 입력하는 리스트이다.

 

첫 번째 입출력 예 [1, 2, 3, 4, 5] 가 입력되면 collect에는 [5, 0, 0] 이 저장될 것이고, 두 번째 입출력 예 [1, 3, 2, 4, 2]가 입력되면 collect에는 [2, 2, 2]가 입력 될 것이다.

 

이렇게 작성된 collect 리스트를 가지고 랭킹을 세우는 함수는 따로 작성하였다.

def rank(arr):
    maxValue = max(arr)
    answer = []
    for i, v in enumerate(arr):
        if v >= maxValue:
            answer.append(i + 1)
    answer.sort()
    return answer

maxValue에 리스트에서 가장 큰 값을 입력 받고, solution 함수와 마찬가지로 enumerate를 사용하여 리스트 항목 중 max값 보다 크거나 같은 값(사실은 더 큰 값은 있을 수 없지만 안전빵으로 넣어놨다)을 answer 리스트에 저장하고, 정렬했다. (사실 리스트를 순차적으로 검색하기 때문에 sort를 안해줘도 오름차순으로 입력될 것이다.)

 

 

 

 

전체 소스코드

def rank(arr):
    maxValue = max(arr)
    answer = []
    for i, v in enumerate(arr):
        if v >= maxValue:
            answer.append(i + 1)
    answer.sort()
    return answer

def solution(answers):
    answer = []
    collect = [0] * 3
    
    for i, ans in enumerate(answers):
        # 1번 수포자
        # 1 2 3 4 5 ...
        a1 = i % 5 + 1
        if ans == a1:
            collect[0] += 1
        
        # 2번 수포자
        # 2 1 / 2 3 / 2 4 / 2 5 ...
        mat2 = [2, 1, 2, 3, 2, 4, 2, 5]
        a2 = i % 8
        if ans == mat2[a2]:
            collect[1] += 1
                
        # 3번 수포자
        # 3 3 / 1 1 / 2 2 / 4 4 / 5 5 ...
        mat3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
        a3 = i % 10
        if ans == mat3[a3]:
            collect[2] += 1
    
    answer = rank(collect)
    return answer

 

테스트 결과

 

반응형
Comments