소소한 컴퓨터 이야기

모의고사

by Cori

문제

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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하는 값을 오름차순 정렬해주세요. 

 

입출력 예 

answer return
[1, 2, 3, 4, 5] [1]
[1, 3, 2, 4, 2]  [1, 2, 3] 

풀이

1. Me

def solution(answers):
    answer = []
    score_p1 = 0; score_p2 = 0; score_p3 = 0
    math_p1 = [1,2,3,4,5] # * 200 
    math_p2 = [2,1,2,3,2,4,2,5] # * 125 
    math_p3 = [3,3,1,1,2,2,4,4,5,5] # * 100 
    # answers *= 200 
    
    for i in range(len(answers)):
        if answers[i] == math_p1[i]:
            score_p1 += 1 
        if answers[i] == math_p2[i]:
            score_p2 += 1
        if answers[i] == math_p3[i]:
            score_p3 += 1 
            
    scores = [score_p1, score_p2, score_p3]
    max_score = max(scores)
    best_p = [x for x in scores if max_score == x] 
    
    if len(best_p) == 1:
        for i, d in enumerate(best_p):
            if d == max_score:
                return [i+1]
    else:
        for i, d in enumerate(best_p):
            if d == max_score:
                answer.append(i+1)
        return answer

처음 풀었을 때 코드 .. runtimeerror도 나고, 정답도 틀리기도 하고 말도 많고 탈도 많았던 코드다. 생각하지 못했던 부분은, 반복적인 답안을 어떻게 구현할 것인가였는데 지금 생각해보면 % 연산을 사용하면 되었다. 지금까지 배워온 내용을 토대로, =for i in range(len(answers)): 이후 부분을 새롭게 작성해보았다. 

def solution(answers):
    answer = []
    score_p1 = 0; score_p2 = 0; score_p3 = 0
    math_p1 = [1,2,3,4,5] 
    math_p2 = [2,1,2,3,2,4,2,5]
    math_p3 = [3,3,1,1,2,2,4,4,5,5] 
    
    for i in range(len(answers)):
        if answers[i] == math_p1[i % len(math_p1)]:
            score_p1 += 1 
        if answers[i] == math_p2[i % len(math_p2)]:
            score_p2 += 1
        if answers[i] == math_p3[i % len(math_p3)]:
            score_p3 += 1
            
    scores = [score_p1, score_p2, score_p3]
    math_p = [1, 2, 3]
    
    max_s = max(scores)
    for a, b in zip(math_p, scores):
        # print(a, b)
        if b == max_s:
            answer.append(a)
    return sorted(answer)

answers는 입력값이므로, 따로 건들이지 않아도 되었고, 수포자들의 반복 패턴에 따라 % 연산을 이용하여 순회하였다. 정답자가 여러 명 나올 경우 정렬을 해 주어야 했기에, 수포자 <-> 정답 수를 묶어줄게 필요했고, zip 함수를 이용했다.

 

2. Others 

def solution(answers):
    pattern1 = [1,2,3,4,5]
    pattern2 = [2,1,2,3,2,4,2,5]
    pattern3 = [3,3,1,1,2,2,4,4,5,5]
    score = [0, 0, 0]
    result = []

    for idx, answer in enumerate(answers):
        if answer == pattern1[idx%len(pattern1)]:
            score[0] += 1
        if answer == pattern2[idx%len(pattern2)]:
            score[1] += 1
        if answer == pattern3[idx%len(pattern3)]:
            score[2] += 1

    for idx, s in enumerate(score):
        if s == max(score):
            result.append(idx+1)

    return result

새롭게 짠 내 코드와 별 차이가 없다. zip 함수를 enumerate로 바꾼 정도 .. ? 수포자의 이름이 정수가 아닐 경우를 생각해보면 zip 함수가 더 유용하게 쓰일 것 같긴 하다.

def solution(answers):
    p = [[1, 2, 3, 4, 5],
         [2, 1, 2, 3, 2, 4, 2, 5],
         [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]]
    s = [0] * len(p)

    for q, a in enumerate(answers):
        for i, v in enumerate(p):
            if a == v[q % len(v)]:
                s[i] += 1
    return [i + 1 for i, v in enumerate(s) if v == max(s)]

간결하고 멋있어서 가져와 본 코드 .. 이해는 잘 못하겠다. 

 

다른 분의 설명에 의하면, 첫번째 반복문에서 enumerate를 썻으니  q=0 일때: a는 anwers의 첫번째 값. 그걸 데리고 가서 두번째 반복문에서 i=0 일때; v는 p의 첫번째값 즉, [1,2,3,4,5]가 됨.. if 절에서 a의 값은 answers의 첫번째이며, v[q% len(v)]는 v중에서 q%len(v)번째를 나타낸다. 여기선, v[0나누기5의나머지]니까  v[0]이며, [1,2,3,4,5] 에서 0번째 놈. 다시 answers의 첫번째랑 v 리스트의 첫번째랑 같냐? 라고 물어서 같으면 해당 위치에 +1 해주는 코드라고 한다.. Wow .. 

'CS > Coding Test' 카테고리의 다른 글

완주하지 못한 선수  (0) 2021.08.24
소수찾기  (0) 2021.08.23
정수 제곱근 판별  (0) 2021.08.23
행렬의 덧셈  (0) 2021.08.23
K번째 수  (0) 2021.08.23

블로그의 정보

코딩하는 오리

Cori

활동하기