[프로그래머스] lv1. 모의고사

문제
문제 설명
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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하는 값을 오름차순 정렬해주세요.

https://programmers.co.kr/learn/courses/30/lessons/42840
코딩테스트 연습 - 모의고사
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다. 1번 수포자가 찍는
programmers.co.kr
풀이
문제를 잘 읽어보면 문제를 맞힌 최대값의 학생만 구하면 된다.
만약 3명 다 0문제 맞췄을 때는 최대값이 0 이고, 3명의 점수가 다 같으므로 오름차순으로 [ 1, 2, 3 ] 이 출력되게 하면된다.
다른 예시로
1번: 3문제,
2번: 3문제,
3번: 1문제 를 맞췄을 때는 [ 1, 2 ]를 리턴하면 된다.
또 다른 예시로
1번: 1문제,
2번: 0문제,
3번: 0문제 를 맞췄을 때는 [ 1 ] 을 리턴하면 된다.
코드
function solution(answers) {
let answer = [];
// 각 학생들의 정답 패턴을 객체에 담아 놓는다.
let students = {
"1": [1,2,3,4,5],
"2" : [2,1,2,3,2,4,2,5],
"3" : [3,3,1,1,2,2,4,4,5,5]
}
// filter를 이용해서 함수 인자로 들어온 정답과 학생들의 정답을 비교하여 맞힌 값을 최신화 시킨다.
for (let key in students) {
students[key] = answers.filter((val, idx) => val === students[key][idx%students[key].length]).length
}
// answer 에 학생 번호와 맞힌 개수를 push한다.
for (let key in students) {
answer.push([key, students[key]])
}
// 맞힌 개수를 기준으로 학생 번호를 오름차순한다.
answer.sort((a, b) => b[1] - a[1])
// 맞힌 값을 기준으로, 1명or2명or3명 리턴한다.
if (answer[0][1] === answer[1][1] && answer[1][1] === answer[2][1])
return [+answer[0][0], +answer[1][0], +answer[2][0]]
else if (answer[0][1] > answer[1][1])
return [+answer[0][0]]
else return [+answer[0][0], +answer[1][0]]
}
// console.log(solution([3,3,2,1,5])) //[3]
// console.log(solution([5,5,4,2,3])) // [1,2,3]
// console.log(solution([1,2,3,4,5])); // [1]
// console.log(solution([1,3,2,4,2])); //[1,2,3]
다른 풀이
function solution(answers) {
let answer = [];
let a1 = [1, 2, 3, 4, 5];
let a2 = [2, 1, 2, 3, 2, 4, 2, 5]
let a3 = [ 3, 3, 1, 1, 2, 2, 4, 4, 5, 5];
let a1c = answers.filter((a,i)=> a === a1[i%a1.length]).length;
let a2c = answers.filter((a,i)=> a === a2[i%a2.length]).length;
let a3c = answers.filter((a,i)=> a === a3[i%a3.length]).length;
let max = Math.max(a1c,a2c,a3c);
if (a1c === max) {answer.push(1)};
if (a2c === max) {answer.push(2)};
if (a3c === max) {answer.push(3)};
return answer;
}
console.log(solution([3,3,2,1,5])) //[3]
느낀점
인자로 10,000자리 배열이 들어왔을 때, 어떻게 1번 학생의 5개 요소의 배열값과 비교할지 많이 고민했다.
값을 비교하는 방법이 %를 이용하면 되겠다는 것을 알게되었다.
그러면 쉽게 1, 2, 3번 학생이 몇 문제를 맞췄는지 쉽게 알 수 있었다.
%를 이용할줄 아는게 첫 번째 이번 문제의 포인트 인것 같다.
두 번째 포인트는 함수 마지막에 값 리턴을 어떻게 해줄 것인가?이다.
나는 문제를 어렵게 풀려고만 해서 그런지 리턴하는 코드가 깨끗하지 못하다.
하지만 다른 풀이의 리턴 방식은 깔끔하다. 내가 원하던 리턴 방식이다.
왜 이런 방식을 나는 생각해내지 못했는가? 하면서 탄식하게 되었다.
마지막으로, 문제를 정확하게 이해하는게 중요하다는 것을 또 한번 깨닫게 되었다.
꼭 문제를 완벽하게 이해하도록 노력하자.