본문 바로가기

코딩테스트

[프로그래머스]모의고사

문제 설명 :

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

오늘은 문제 푸는데 좀 시간이 오래걸렸다. 

 

def solution(answers):
    answer = []
    student = {1 : [1,2,3,4,5], 2 : [2,1,2,3,2,4,2,5], 3 : [3,3,1,1,2,2,4,4,5,5],'oneAnswerNum':0, 'twoAnswerNum':0,'threeAnswerNum':0,'one':[],'two':[],'three':[]}
    
    # 1.각 학생들의 정답을 배열로 만들기 student['one'],student['two'],student['three']
    studentsNum = [1,2,3]
    students = ['one','two','three']
    for a,n in zip(students,studentsNum):
         for i in range(len(answers)):
            student[a].append(student[n][i%len(student[n])])

    # 2.각 '학생들의 정답'을 '정답'과 비교하기 
    for i in students:
         for a,b in zip(answers,student[i]):
            if(a == b):
                student[i+"AnswerNum"] += 1
            else:
                continue

    # 3. 각 학생들 정답 사이의 최댓값 구하기
    studentCorrectAnswerNum = [student['oneAnswerNum'],student['twoAnswerNum'],student['threeAnswerNum']]
    maxNum = max(studentCorrectAnswerNum)
    maxOfNum = studentCorrectAnswerNum.count(maxNum)

    # 4. 각 학생들 정답 사이의 최댓값 개수 확인 후 answer에 넣기. 
    if (maxOfNum == 1):
        answer.append(studentCorrectAnswerNum.index(maxNum)+1)
    else:
        maxList = list(filter(lambda x: studentCorrectAnswerNum[x] == maxNum, range(len(studentCorrectAnswerNum))))
        maxList.sort()
        for i in maxList:
            answer.append(i + 1)

    return answer

문제를 풀 때, 내가 고려했던 생각의 프로세스는 다음과 같다. 

 

1.먼저 학생들이 정답을 찍는 패턴을 배열화한다. 

2.정답과 학생들이 찍은 답을 배열의 순서대로 나란히 비교한다. 비교하면서 정답인 경우 각각의 점수를 +1한다. 

3.최종적으로 나온 점수들을 비교한다. 


1.먼저 학생들이 정답을 찍는 패턴을 배열화한다 :

-> 여기서 시간이 많이 잡아먹혔던 것 같다. 먼저는 학생들이 답을 찍는 패턴을 배열화 한다하더라도, 그 배열의 길이가 정답의 길이와 같아야 한다. 그래야 내가 2번에서 사용하려는 zip함수를 사용할 수 있기 때문이다. 이 방법을 떠올리는데 많은 시간이 들어갔는데, 결국 생각해낸 방법은 나머지 값을 통해서 배열을 하나씩 더해가는 것이다. 

->studentsNum = [1,2,3]

    students = ['one','two','three']

    for a,n in zip(students,studentsNum):

         for i in range(len(answers)):

            student[a].append(student[n][i%len(student[n])]) # 배열의 수만큼 cycle을 돌릴 수 있도록 만든 것이다. 

 

 

2.정답과 학생들이 찍은 답을 배열의 순서대로 나란히 비교한다.비교하면서 정답인 경우 각각의 점수를 +1한다.  :

-> 여기서는 그렇게 어렵지 않았다. 바로 zip함수를 이용해서 각각의 수를 비교해야겠다고 생각했었다. 

-> for i in students:

         for a,b in zip(answers,student[i]):

            if(a == b):

                student[i+"AnswerNum"] += 1

            else:

                continue

 

3.최종적으로 나온 점수들을 비교한다. :

->

# 3. 각 학생들 정답 사이의 최댓값 구하기

    studentCorrectAnswerNum = [student['oneAnswerNum'],student['twoAnswerNum'],student['threeAnswerNum']]

    maxNum = max(studentCorrectAnswerNum) -> 배열 내의 최댓값을 구하기

    maxOfNum = studentCorrectAnswerNum.count(maxNum)

 

    # 4. 각 학생들 정답 사이의 최댓값 개수 확인 후 answer에 넣기. 

    if (maxOfNum == 1):

        answer.append(studentCorrectAnswerNum.index(maxNum)+1)

    else:

        maxList = list(filter(lambda x: studentCorrectAnswerNum[x] == maxNum, range(len(studentCorrectAnswerNum)))) -> 배열 안에서 특정요소가 있는 인덱스 값을 구하기 

        maxList.sort() -> 오름차순으로 정렬하기

        for i in maxList:

            answer.append(i + 1)

 

    return answer

 

 


이렇게 문제를 풀고서, 약간의 기쁨을 누린 후에 다른 사람들의 정답을 보니 약간의 자괴감이 들긴했다. 저렇게 간단하고 깔끔하게 적을 수 있는 것을 나는 이토록 복잡하게 적었구나 싶은 생각이 들었다. 그래도 그들의 문제풀이를 보면서 enumarate라는 함수를 이용하면 더 깔끔하게 접근할 수 있는 문제였다는 것을 배울 수 있어서 감사했다.