Stay Hungry Stay Foolish

프로그래머스 코딩테스트/Level 1

[Programmers] L1. 모의고사 (완전탐색/Python)

dev스카이 2024. 11. 6. 16:23

[문제 링크] 👇

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


풀이

각 수포자의 패턴 정의

  • 각 수포자는 문제를 찍는 일정한 패턴을 가지고 있다.
  • 첫 번째 수포자는 [1, 2, 3, 4, 5], 두 번째는 [2, 1, 2, 3, 2, 4, 2, 5], 세 번째는 [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]라는 패턴을 반복하며 답을 찍는다.

정답과 비교하여 맞힌 개수 계산

  • 주어진 answers 리스트와 각 수포자의 패턴을 반복 비교하여 맞힌 개수를 센다.
  • j 변수를 사용해 각 수포자 패턴의 인덱스를 맞춰 가며 비교하고, j가 패턴 길이에 도달하면 다시 0으로 초기화하여 패턴을 반복한다.

모든 수포자의 점수 비교

  • 각 수포자가 맞힌 점수를 cnt 리스트에 저장한다.
  • cnt에서 가장 높은 점수를 찾고, 이를 통해 해당 점수를 받은 수포자의 번호를 answer 리스트에 추가한다.

가장 많은 문제를 맞힌 수포자 반환

  • answer 리스트에는 최고 점수를 받은 수포자의 번호가 들어가며, 오름차순으로 반환한다.

Solution

def correct(student_answer, answers):  # 정답 계산 함수
    cnt, j = 0, 0
    for i in range(len(answers)):
        if answers[i] == student_answer[j]:  
            cnt += 1
        j += 1  # 다음 문제로 
        if j >= len(student_answer): 
            j = 0

    return cnt

def solution(answers):
    answer = []
    one = correct([1, 2, 3, 4, 5], answers)  # 1번 수포자
    two = correct([2, 1, 2, 3, 2, 4, 2, 5], answers)  # 2버 수포자
    three = correct([3, 3, 1, 1, 2, 2, 4, 4, 5, 5], answers)  # 3번 수포자
    cnt = [one, two, three]  # 정답 개수 저장
    
    max_cnt = max(cnt)  # 정답 개수 중 최댓값 저장
    for i in range(3):  
        if max_cnt == cnt[i]:  # 최대 정답 수와 같으면
            answer.append(i + 1)  # 결과 리스트에 인덱스를 추가한다.
    return answer

 

 

선할 점

  • correct() 함수에서 인덱스 관리를 간결하게 만들기 위해 enumerate()와 모듈러 연산 %를 사용할 수 있다.
  • solution() 함수에서 for 루프 없이 리스트 컴프리헨션으로 최고 점수를 얻은 학생을 찾아 반환할 수 있다.

 

개선된 코드

def correct(student_answer, answers):
    return sum(1 for i, ans in enumerate(answers) if ans == student_answer[i % len(student_answer)])

def solution(answers):
    patterns = [
        [1, 2, 3, 4, 5], 
        [2, 1, 2, 3, 2, 4, 2, 5], 
        [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    ]
    scores = [correct(pattern, answers) for pattern in patterns]
    max_score = max(scores)
    
    return [i + 1 for i, score in enumerate(scores) if score == max_score]

 


👩‍💻 회고

이 문제는 Level 1 인데도 상당히 긴 코드를 작성해야 했다. 내 풀이만 그런 줄 알았는데 다른 사람들도 만만치 않게 길어서 맞게 풀었구나 싶었다. 

 

의외로 에러가 난 곳은 max 값을 찾을 때였다. 다음은 초기에 작성했던 코드이다.

max_answer = 0
    for i in range(len(cnt)):
        if cnt[i] >= max_answer:
            max_answer = cnt[i]
            answer.append(i + 1)
  • 코드에서는 `if cnt[i] >= max_answer` 조건을 사용해 최고 점수를 갱신하면서 바로 `answer` 배열에 점수가 같은 사람도 추가하고 있다.
  • 하지만, 이렇게 하면 최고 점수를 갱신할 때 이전에 추가된 사람들을 `answer` 배열에서 제거하지 않으면서, 최종적으로 가장 높은 점수를 받은 사람들이 아닌, 그 이전에 고려된 사람들까지 포함할 수 있다.

이 부분까진 미처 고려하지 못했어서 아쉬웠다. 다행히도 바로 수정해서 2트만에 성공했다. 솔직히 코드가 너무 길어져서 제출이 안 될 줄 알았다. 연습문제 말고는 자료 구조나 알고리즘 문제는 이런식으로 풀어도 쫄지 말자. 

 

개선된 코드도 다시 보며 더 효율적인 코드로 작성하도록 하자.