알고리즘 문제 - Programmers School #47 모의고사
아래는 문제 내용이다.
Description
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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하는 값을 오름차순 정렬해주세요.
세 수포자 모두 다른 길이의 패턴으로 문제를 찍었고, 그렇게 산출된 점수 중 최고 득점자의 그룹을 계산한다.
처음에는 아래와 같이 답을 제출했다.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Algorithm_016
{
public class TrialExam
{
public int[] solution(int[] problemAnswers)
{
int[] scores = new int[3] { 0, 0, 0 }; // 각 응시자의 점수
int[] examinee1Pattern = new int[] { 1, 2, 3, 4, 5 }; // 응시자의 찍기 패턴
int[] examinee2Pattern = new int[] { 2, 1, 2, 3, 2, 4, 2, 5 };
int[] examinee3Pattern = new int[] { 3, 3, 1, 1, 2, 2, 4, 4, 5, 5 };
int examinee1TrialIndex = 0; // 응시자의 찍기 패턴 번호
int examinee2TrialIndex = 0; // ex) 응시자1 : 1,2,3,4,5 -> 1,2,3,~ 처음부터 다시 돈다.
int examinee3TrialIndex = 0;
int problemIndex = 0; // 문제 번호
while (problemIndex < problemAnswers.Length) // 주어진 문제 수만큼 반복
{
if (examinee1TrialIndex == examinee1Pattern.Length) // 응시자가 찍는 번호가 패턴의 끝에 왔으면
{
examinee1TrialIndex = 0; // 다시 번호를 0으로 돌려서 패턴의 처음부터 찍도록 한다.
}
if (examinee1Pattern[examinee1TrialIndex] == problemAnswers[problemIndex]) // 찍은 번호가 정답이면
{
scores[0]++; // 점수 +1
}
examinee1TrialIndex++; // 다음 찍기 번호
if (examinee2TrialIndex == examinee2Pattern.Length)
{
examinee2TrialIndex = 0;
}
if (examinee2Pattern[examinee2TrialIndex] == problemAnswers[problemIndex])
{
scores[1]++;
}
examinee2TrialIndex++;
if (examinee3TrialIndex == examinee3Pattern.Length)
{
examinee3TrialIndex = 0;
}
if (examinee3Pattern[examinee3TrialIndex] == problemAnswers[problemIndex])
{
scores[2]++;
}
examinee3TrialIndex++;
problemIndex++;
}
int highestScore = scores.Max(); // 점수 최댓값
var rankerList = new List<int>(); // 최고 득점자 그룹
for (int i = 0; i < scores.Length; i++) // 응시자 수만큼 반복
{
if (scores[i] == highestScore) // 응시자 점수가 최고점이면
{
rankerList.Add(i + 1); // 그룹에 추가
}
}
return rankerList.ToArray();
}
}
}
다시 봐도 기가 찬다. 응시자가 3명이라서 3개 경우를 전부 작성했다. 응시자가 5명만 넘어갔어도 이따위로 못했을텐데.
반복되는 로직을 반복문으로 최소화한다.
그렇게 개선한 답안은 아래와 같다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Algorithm_016
{
public class TrialExam
{
public int[] solution(int[] problemAnswers)
{
int[] scores = new int[] { 0, 0, 0 }; // 각 응시자의 점수
int[][] examineePatterns = new int[][] // 응시자의 찍기 패턴
{
new int []{ 1, 2, 3, 4, 5 },
new int []{ 2, 1, 2, 3, 2, 4, 2, 5 },
new int []{ 3, 3, 1, 1, 2, 2, 4, 4, 5, 5 }
};
int[] examineeTrialIndexes = new int[] { 0, 0, 0 }; // 응시자의 찍기 패턴 번호
int problemIndex = 0; // 문제 번호
while (problemIndex < problemAnswers.Length) // 주어진 문제 수만큼 반복
{
for (int i = 0; i < scores.Length; i++) // 응시자 수만큼 반복
{
if (examineeTrialIndexes[i] == examineePatterns[i].Length) // 응시자가 찍는 번호가 패턴의 끝에 왔으면
{
examineeTrialIndexes[i] = 0; // 다시 번호를 0으로 돌려서 패턴의 처음부터 찍도록 한다.
}
if (examineePatterns[i][examineeTrialIndexes[i]] == problemAnswers[problemIndex]) // 찍은 번호가 정답이면
{
scores[i]++; // 점수 +1
}
examineeTrialIndexes[i]++; // 다음 찍기 번호
}
problemIndex++;
}
int highestScore = scores.Max(); // 점수 최댓값
var rankerList = new List<int>(); // 최고 득점자 그룹
for (int i = 0; i < scores.Length; i++) // 응시자 수만큼 반복
{
if (scores[i] == highestScore) // 응시자 점수가 최고점이면
{
rankerList.Add(i + 1); // 그룹에 추가
}
}
return rankerList.ToArray();
}
}
}
n 명의 응시자 점수, 찍기패턴(가변 배열), 찍는 번호 순서 전부 배열로 만들고, 점수 계산 과정도 n번 반복하도록 반복문을 추가했다.
그 어디에도 응시자가 3명이라는 말이 없다. 즉, 특정 찍기 패턴을 가진 응시자가 아무리 많아도 최고 득점자 그룹을 쉽게 반환할 수 있는 코드다.
사실 이런 식으로 만들어놓은 코드를 수정해서 다시 제출하는 일 거의 없긴 한데, 꽤 괜찮은 과정이라고 생각한다.
'UNITY' 카테고리의 다른 글
| UNITY_20231013[팀 과제, Ray in UNITY3D] (0) | 2023.10.17 |
|---|---|
| UNITY_20231012[개인과제 완료] (0) | 2023.10.12 |
| UNITY_20231005[유니티 3D 강의 시작, 알고리즘 문제 풀이] (0) | 2023.10.05 |
| UNITY_20231004[팀 과제-로그라이크 RPG - 완료] (0) | 2023.10.04 |
| UNITY_20231002[팀 과제-로그라이크 RPG - 벽, 방, 복도 만들기] (0) | 2023.09.27 |