본문 바로가기
프로그래머스/Python

[Python 프로그래머스] 모의고사 - 초보를 위한 자세한 설명 | 완전탐색 | 브루트 포스 알고리즘

by 그레이슨킴 2021. 5. 30.

문제 주소:
https://programmers.co.kr/learn/courses/30/lessons/42840

 

완전탐색 문제입니다. 다른 말로는 브루트 포스(Brute force) 라고 합니다.
가능한 모든 경우의 수를 대입하여 문제를 해결하는 방식으로써 오래 걸리는 데다 자원이 엄청나게 깨져서 얼핏 보면 무식하다고 생각할 수도 있겠지만, 항상 정확도 100%를 보장한다는 특징이 있습니다.


문제 설명

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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문제씩을 맞췄습니다.

나의 풀이

def solution(answers):
    people = {
        "supo1" : [1,2,3,4,5,1,2,3,4,5],
        "supo2" : [2,1,2,3,2,4,2,5]
        "supo3" : [3,3,1,1,2,2,4,4,5,5]
    }    # 수포자들의 데이터를 dictionary 자료형으로 저장
    answer = []
    score = 0
    scores = []
    highest = 0
    
    for i in range(1,4):
        temp = "supo" + str(i)    # people 변수의 key 이름 저장
        for j in range(len(answers)):
            if i == 2: idx = j % 8    # supo2 의 인덱스 설정
            else: idx = j % 10    # supo1 과 supo3 의 인덱스 설정
            if answers[j] == people[temp][idx]:
                score += 1
        if score > highest:
            highest = score    # 세 사람의 점수 중 가장 높은 점수를 저장
        scores.append(score)    # 각 사람의 점수를 scores 자료형에 저장
        score = 0
    
    for n in range(3):
        if scores[n] == highest:    # 가장 높은 점수와 모든 수포자들의 점수를 비교하여 일치하면
            answer.append(n+1)      # answer 자료형에 해당되는 수포자 번호 넣기
    return answer

모든 케이스를 통과하기는 하나 런타임 에러가 떴습니다.


가장 "좋아요" 를 많이 받은 풀이

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


>>알고리즘

1. 수포자들의 데이터를 list 형태로 저장
2. 반복문으로 answer 값과 수포자들이 찍은 값을 비교 후 각 사람의 점수를 score에 저장
3. score에서 가장 큰 값과 다른 모든 값을 비교해 일치할 경우 해당 인덱스에 +1 한 값을 result에 넣음(append)

>>기타 문법 설명

1. enumerate 함수
enumerate 함수는 for 문과 함께 쓰이는 함수로 순서가 있는 자료형(list, set, tuple, dictionary, string)을 입력으로 받아 인덱스 값과 함께 리턴합니다. 예를 들어

data = ['a', 'b', 'c', 'd']
for idx, value in enumerate(data):
	print(idx, value)

output:

0 a
1 b
2 c
3 d


다음과 같이 인덱스 시작 값을 정할 수도 있습니다.

data = ['a', 'b', 'c']
for idx, value in enumerate(data, start=100):
	print(idx, value)

output:

100 a
101 b
102 c

 

2. max 함수
인자의 가장 큰 값을 반환합니다.

a = [4, 3, 2, 1, 9]
print(max(a))   # 9 출력

b = 'Hello World'
print(max(b))   # r 출력

짧은 후기

어렵네요.

댓글