3. 한번 해볼까? (Mission2)

나를 죽이지 못하는 고통은, 나를 더욱 더 강하게 해줄 뿐이다.

코딩테스트 풀어보기

난이도는 기본 문법만을 배우고나서는 생각보다 어려울 것입니다. 하지만 해당 문제 안에서 많이 쓰는 문법들이 들어가 있으니 힘내봅시다.

문제를 읽어보셨나요? 무슨 말인지 어디부터 접근해야할지 모르겠다라고 생각하신다면 밑의 힌트 내용을 찾아서 한번 더 보고 다시 문제를 풀어 봅시다.

Hint : lists, append, for, if, boolean, dictionary, sort, enumerate

1. 준비하기

def solution(answers):
    answer = []
    return answer

01. 기본

위의 링크에서 문제를 확인해보면 도대체 문제도 이해가 안되고 코드로 답을 적으려니 막막하실거라 생각합니다. 프로그래머스에서 문제 풀이 언어 토글목록을 눌러서 파이썬으로 변경하면 위와 같이 함수 정의하는 내용은 있는데 나보고 어쩌라고 하는 생각이 드시겠죠

그래도 너무 걱정 안 하셔도 됩니다. 오늘 문제 풀이 방법에 대해서 배워볼 것이고 다음에는 혼자서도 충분히 푸실 수 있을 것이기 때문입니다.

02. 문제 읽기

혹시 잘 이해가 되지 않으시나요?? 삐빅~ 정상입니다.

문제 설명

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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명의 수포자들이 같은 찍는 방식으로 찍는다는 규칙이 있네요 이것은 어떻게 나타내면 좋을지를 먼저 생각해 봅니다.

두번째로는 이렇게 찍는 번호와 실제로 전달받은 answers 인자가 동일한지 판별하는 부분이 있어야 겠네요 . 나열된 값을 순서대로 순회하면서 값을 비교해야하니 "for"문을 사용하면 될 것 같고 같은지 아닌지를 판별해야하니 "if"문도 사용해야 될 것이라고 생각됩니다. 이런 식으로 처음 할일 두번째 할일을 생각하면서 코드상으로는 어떻게 표현 할 수 있을지를 생각해보세요 분명 해결 방법이 보일 것이라고 생각됩니다. 이제 다시한번 문제를 둘러보시고 그래도 방향을 잡기 힘들다면 밑을 확인해주세요

03. 문제를 풀기위한 방향성 설정하기

똑같은 문제를 해결해 나가는 과정에서도 사람에 따라서 많은 방향성이 있다고 생각됩니다.

위의 문제인 경우만해도 여러가지 문제 풀이 방향성이 있을 거라고 생각됩니다 여기에 몇가지 접근할 수 있는 방법을 적어보겠습니다.

  1. 수포자가 찍는 방법과 정답을 비교해서 3명의 사람별로 맞춘 횟수를 카운팅 한 상태에서 각각의 사람들이 맞춘 횟수를 조건문을 이용하여 비교하고 모든 경우의 수에 따라서 answer 값을 바꾸면서 답을 리턴해주는 경우

if 첫번째 사람과 두번째 사람이 맞춘 횟수가 같고 그리고 두번째 사람이 맞춘 횟수와 세번째 사람이 맞춘 횟수가 같을때:
    answer 배열에 [1,2,3] 넣고 리턴
elif 첫번째와 두번째는 같고 그리고 두번째와 세번째중에는 두번째가 더 클경우 
    ...
elif 
    ...
  1. 수포자가 찍는 방법과 정답을 비교한 값으로 3명이 맞춘 횟수를 구하는 것은 동일하나 dictionary에 담아 두고 그 밸류 값중 가장 큰 값을 구해서 dictionary에서 순서대로 값이 같은지 확인하고 해당 값을 순서대로 answer 배열에 붙여주는 방법

    rank[1] = cnt_one
    rank[2] = cnt_two
    rank[3] = cnt_three
    
    all_rank_values = rank.values()
    max_rank_values = max(all_rank_values)
    
    for i in range(1, len(rank)+1):
        if rank[i] == max_rank_values:
            answer.append(i)
1번 방식으로 구현하하게 되면 구현 방법은 명시적이겠지만 모든 경우의 수에 대해서 모든 조건문을 분기처리를 해줘야하는 불편함이 있습니다. 하지만 2번과 같은 방식으로 구현 방향성을 잡게된다면 사람이 3명일때나 4명일때나 rank["key"] = "value" 의 값만 늘려도 되니 확장성이 더 좋은 것을 알 수 있습니다. 언제나 코드를 구성하는 것에는 왕도는 없다고 생각하지만 원하는 기능과 향후 확장성등을 생각해서 문제를 풀어 나가는것이 중요한것을 잊지마세요

04. 실제로 풀어보기

이렇게 주는 힌트도 한가지 방법일 뿐이라는 것 잊지마세요~

// 이런 흐름으로 해결할 수 있구나만 확인해보세요
def solution(answers):
    answer = []

    cnt_one = 0 # 변수의 이름에 집중해보세요 cnt_one은 첫번째 수포자가 몇번 맞췄는지를 저장해놓기 위한 변수입니다.
    cnt_two = 0 # 그렇다면 cnt_two와 cnt_three의 의미도 알 수 있겠죠?
    cnt_three = 0
    
    one = [1, 2, 3, 4, 5]
    two = [2, 1, 2, 3, 2, 4, 2, 5]
    three = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    
    rank = {} # 딕셔너리로 사용할 rank를 선언합니다.

    for i, ans in enumerate(answers):
        if 첫번째 수포자가 맞췄는지 확인:
            첫번째 수포자의 cnt 변수를 1증가
        if 두번째 수포자가 맞췄는지 확인:
            두번째 수포자의 cnt 변수를 1증가
        if 세번째 수포자가 맞췄는지 확인:
            세번째 수포자의 cnt 변수를 1증가
    
    # rank라는 딕셔너리를 cnt 변수로 구성   
    
    all_rank_values = rank.values() // value값 전체를 배열로 반환
    max_rank_values = max(all_rank_values) // 이중 가장 큰값을 추출
    
    for i in range(1, len(rank)+1): // for문의 index 자체를 몇번째 수포자 인지 확인하는 용도로 사용 
        if rank[i] == max_rank_values:
            answer.append(i) // 위에서 구한 제일 많이 맞춘 경우의 값과 일치하면 해당 사람 번호를 answer에 추가

    return answer
    
    '''
    위의 함수에 들어갈 answers는 위에 제시되긴 하였지만 밑과 같은 숫자를 넣도록 되어있습니다. 
    answers	return
    [1,2,3,4,5]	[1]
    [1,3,2,4,2]	[1,2,3]
    '''

    

Last updated