# 3. 한번 해볼까? (Mission2)

<figure><img src="https://3402779428-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTLirNrcoAGymWQdO0PHK%2Fuploads%2FrrhUJnTApbR7ASna653z%2Fimage.png?alt=media&#x26;token=94b76006-f624-47e3-a7d1-2b86a5946ef0" alt=""><figcaption></figcaption></figure>

**코딩테스트 풀어보기**

{% embed url="<https://school.programmers.co.kr/learn/courses/30/lessons/42840>" %}

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

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

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

## 1. 준비하기

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

### 01. 기본

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

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

### 02. 문제 읽기

{% hint style="info" %}
혹시  잘 이해가 되지 않으시나요?? 삐빅\~ 정상입니다.
{% endhint %}

**문제 설명**

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

{% hint style="info" %}
:smile: : 문제를 읽다보면 언제나 생각하는 것이 한글로도 이해가 잘 되지 않는데 이걸 어떻게 코드로 나타내라는 거지라는 생각이 드는것 같아요. 하지만 큰 문제를 작은 단위로 나눠서 생각해보는 습관을 들이다보면 조금씩 익숙해지는 자신의 모습을 보실 수 있을 거라고 생각합니다.\
\
첫번째로는 여기서는 3명의 수포자들이 같은 찍는 방식으로 찍는다는 규칙이 있네요 이것은 어떻게 나타내면 좋을지를 먼저 생각해 봅니다.

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

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

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

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

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

```python
if 첫번째 사람과 두번째 사람이 맞춘 횟수가 같고 그리고 두번째 사람이 맞춘 횟수와 세번째 사람이 맞춘 횟수가 같을때:
    answer 배열에 [1,2,3] 넣고 리턴
elif 첫번째와 두번째는 같고 그리고 두번째와 세번째중에는 두번째가 더 클경우 
    ...
elif 
    ...
```

2. 수포자가 찍는 방법과 정답을 비교한 값으로 3명이 맞춘 횟수를 구하는 것은 동일하나 dictionary에 담아 두고 그 밸류 값중 가장 큰 값을 구해서 dictionary에서 순서대로 값이 같은지 확인하고 해당 값을 순서대로 answer 배열에 붙여주는 방법&#x20;

```python
    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)
```

<details>

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

</details>

### 04. 실제로 풀어보기

{% hint style="info" %}
이렇게 주는 힌트도 한가지 방법일 뿐이라는 것 잊지마세요\~
{% endhint %}

```python
// 이런 흐름으로 해결할 수 있구나만 확인해보세요
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]
    '''

    
```
