수포자 중 최다 득점자 찾기

ch.2·2024년 6월 19일
0

코딩 테스트

목록 보기
1/21

문제

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

입출력 예
answers return
[1,2,3,4,5][1]
[1,3,2,4,2][1,2,3]

입출력 예 #1

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

입출력 예 #2

모든 사람이 2문제씩을 맞췄습니다.


첫 번째 시도

방향성 힌트: 3명의 수포자들이 같은 방식으로 찍는다는 규칙을 어떻게 나타내면 좋을지 생각하기.

one_list = ["1","2","3","4","5"]
two_list = ["2","1","2","3","2","4","2","5"]
three_list = ["3","3","1","1","2","2","4","4","5","5"]

시도 이유:

  • 사실 수포자들의 답안이 반복적이라서 전부 다 적는 것이 아닌, 다른 방법이 있을 것이라고 생각하였다. 문자열 리스트로 적는 것이 잘못된 것이라는 것을 깨달았다.

틀린 이유: 문자열 리스트 보다 정수형 리스트를 사용해야 한다.

  • 정수형 리스트를 사용하면 단순한 비교 연산을 사용할 수 있다.
  • 정수형 리스트를 사용하면 문자열로 표현하는 것보다 간편하게 리스트 연산을 사용할 수 있다.

발전 방향: 정수형 리스트 사용하기.

두 번째 시도

방향성 힌트: 수포자들이 찍은 번호와 정답 배열인 answers가 동일한지 판별하는 부분 만들기.
문법 힌트:

  • 나열된 값을 순서대로 순회하며 값을 비교해야 하니 for문 사용.
  • 정답이 맞는지 아닌지를 판별해야 하니 if문 사용.
nomath1 = [1,2,3,4,5]
nomath2 = [2,1,2,3,2,4,2,5]
nomath3 = [3,3,1,1,2,2,4,4,5,5]

score = [nomath1, nomath2, nomath3]

for answers == nomath1:
    score += 1
    print(f"수포자1은 {score} 문제를 맞혔습니다.")
for answers == nomath2:
    score += 1
    print(f"수포자2는 {score} 문제를 맞혔습니다.")    
for answers == nomath3:
    score += 1
    print(f"수포자3은 {score} 문제를 맞혔습니다.")

시도 이유:

  • 수포자1, 수포자2, 수포자3을 각각 nomath1,2,3으로 분류하여 정수형 리스트를 만들었다.
  • 수포자들의 점수와 정답을 비교하는 리스트가 필요할 것 같아 score 리스트를 만들었다.
  • 수포자들의 답안과 answers가 동일할 경우, score에 1씩 추가하여 각각 몇 문제를 맞췄는지 알 수 있도록 했다.

틀린 이유:

  • 현재 내 score 리스트에는 nomath1,2,3이 저장되어 있는데, 이것은 수포자들의 찍는 방식을 저장하고 있는 리스트다. 각 수포자들의 점수를 저장하려면 별도의 리스트가 필요하다.
  • for 부분은 answers 리스트와 각 수포자들의 찍는 방식을 비교하는 것이 아니고, answers 리스트 자체가 nomath1,2,3과 일치하는지 확인하기 위한 방식이다. 따라서 이 부분은 항상 False가 될 것이다.
  • score은 수포자들의 찍는 방식을 저장하고 있는 리스트이므로 이 값을 1씩 증가시키는 것은 나의 의도와 어긋나는, 올바르지 않는 방법이다.

발전 방향:
1. score 리스트를 각 수포자들의 점수를 저장하는 용도로 사용하기 위해서 score=[0,0,0]을 사용하기.

  • 모든 수포자들의 점수를 0으로 초기화시키면 점수를 누적해서 저장할 수 있다.
  • 정답을 맞출 때마다 해당 수포자의 점수를 1씩 증가시킬 수 있다.
  • score[0]에는 수포자1의 점수, score[1]에는 수포자2의 점수, score[2]에는 수포자3의 점수가 저장될 것이다.
  1. 현재 for문을 for i in range(len(answers)): 으로 바꾸기.
  • answers 리스트의 길이만큼 반복문을 실행하기 위한 부분이다. 문제의 개수만큼 반복하여 각 문제의 정답과 수포자들의 찍는 방식을 비교하기 위한 부분이다.
  • i는 반복문의 인덱스 변수이다. 이를 사용하여 answers 리스트의 각 요소를 확인하고, 해당 요소가 수포자들의 찍는 방식과 일치하는지 확인할 수 있다.
  • range(len(answers))는 0부터 answers 리스트의 길이 -1까지의 숫자 시퀀스를 생성하는 부분이다.
  • 각 반복시, 변수 i는 0부터 시작해 answers 리스트의 길이 -1까지 순차적으로 1씩 증가하며 answers 리스트의 요소에 접근할 수 있게 된다.
  1. 'if'문을 사용하여 answers 와 nomath1,2,3이 일치하는지 확인하기.

세 번째 시도

nomath1 = [1,2,3,4,5]
nomath2 = [2,1,2,3,2,4,2,5]
nomath3 = [3,3,1,1,2,2,4,4,5,5]

score = [0,0,0]
for i in range(len(answers)):
    if nomath1 == answers[i]:
        score[0] += 1
    if nomath2 == answers[i]:
        score[1] += 1
    if nomath3 == answers[i]:
        score[2] += 1
        
winner=max(score)

시도 이유:

  • 각 수포자들의 답안이 answers 리스트에 있는 답안과 일치한다면 score 리스트에 1씩 누적한다.
  • score가 높은 사람을 winner로 지정한다. 하지만 최다 득점자가 여럿일 경우는 오류가 생길 것 같다.

틀린 이유:

  • nomath1 전체와 answers[i]값을 비교하게 되는 것이므로 각 답안별 정답 수를 알 수는 있지만, nomath1 전체에서 맞은 답안이 몇 개인지 찾기에는 적합하지 않다.

발전 방향:
1. if nomath1,2,3 == answers[i]: 부분을 if answers[i] == nomath1,2,3[i % len(nomath1,2,3)]:으로 바꾸기.

  • i % len(nomath1,2,3)을 사용해 nomath1,2,3의 요소, 수포자들의 답안 패턴을 순환적으로 적용할 수 있다.
  • i는 문제의 순서, 문제 번호를 뜻하고, len(nomath1,2,3)은 각 수포자들의 답안 패턴 길이 5,8,10을 나타낸다.
  • 수포자1의 경우로 예시를 들면, 첫 번째 문제에서는 0 % 5 = 0 이 되어 답안 1이 적용되고, 두 번째 문제에서는 1 % 5 = 1 이 되어 답안 2가 적용된다.
  1. answer = []를 이용해, 최다 득점자가 여럿일 경우 올바르게 작성할 수 있도록 한다.
  • answer = []는 빈 리스트이다. 이를 이용해 최다 득점자가 여럿일 경우, 그들을 이 리스트에 차례대로 작성할 수 있다.
  • 각 수포자들의 점수가 max(score)와 같은지 확인하고 그들을 answer 리스트에 추가해야 한다.

네 번째 시도

def solution(answers):

nomath1 = [1,2,3,4,5]
nomath2 = [2,1,2,3,2,4,2,5]
nomath3 = [3,3,1,1,2,2,4,4,5,5]

score = [0,0,0]
    for i in range(len(answers)):
        if answers[i] == nomath1[i%len(nomath1)]:
            score[0] += 1
        if answers[i] == nomath2[i%len(nomath2)]:
            score[1] += 1
        if answers[i] == nomath3[i%len(nomath3)]:
            score[2] += 1

winner = max(score)
    answer = []
    for i in range(len(score)):
        if score[i] == max(score):
        answer.append(i+1)
        
    return answer 
      

틀린 이유:

  • def solution(answers): 코드 이후에 들여쓰기를 올바르게 하지 않았다.
  • if score[i] == max(score): 부분은 반복문이 실행될 때마다 매번 max 함수를 호출하게 되므로, 불필요한 계산이 생긴다.
  • if 조건문에 해당하는 코드에 들여쓰기를 올바르게 하지 않았다.

발전 방향:

  • 이미 max(score)를 지정한 winner 변수가 있으므로, winner를 쓰는 것이 불필요한 계산을 줄여준다.

다섯 번째 시도

def solution(answers):
    nomath1 = [1,2,3,4,5]
    nomath2 = [2,1,2,3,2,4,2,5]
    nomath3 = [3,3,1,1,2,2,4,4,5,5]

    score = [0,0,0]
    for i in range(len(answers)):
        if answers[i] == nomath1[i%len(nomath1)]:
            score[0] += 1
        if answers[i] == nomath2[i%len(nomath2)]:
            score[1] += 1
        if answers[i] == nomath3[i%len(nomath3)]:
            score[2] += 1

    winner = max(score)
    answer = []
    for i in range(len(score)):
        if score[i] == winner:
            answer.append(i+1)
        
    return answer 

테스트 결과 (~˘▾˘)~
2개 중 2개 성공

tip!

파이썬은 들여쓰기를 매우 엄격하게 요구하기 때문에, 함수 내부의 코드는 반드시! 한 수준 들여쓰기를 해야 한다.

profile
데이터 분석 공부중

0개의 댓글