function solution(answers) {
// 각 학생들 찍는 패턴을 score 배열에 저장
let score = [
[1, 2, 3, 4, 5],
[2, 1, 2, 3, 2, 4, 2, 5],
[3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
]
// 찍어서 맞춘 갯수
let count1 = 0
let count2 = 0
let count3 = 0
// 문제 채점 판별
for (let i = 0; i < answers.length; i++) {
// i % 찍는 패턴 길이로 진행하면 인덱스에 의존없이 조건이 맞아 떨어짐
if (answers[i] === score[0][i % score[0].length] ) count1++
if (answers[i] === score[1][i % score[1].length] ) count2++
if (answers[i] === score[2][i % score[2].length] ) count3++
}
// 각 맞춘 갯수들을 key값 1,2,3 번째로 나눠 저장
let obj = {1: count1, 2: count2, 3: count3}
// 최종 결과 저장소 -> 첫번째 1번 학생 저장 (queue 저장하는 방식)
let result = [1]
// 첫번째 1번 학생의 맞춘 갯수 저장
let maxNum = obj[1]
for (let i = 2; i <= Object.keys(obj).length; i++) {
// 첫번째 학생과 다음 번째의 학생 점수 갯수 비교
if (maxNum < obj[i]) {
// 더 클 경우 maxNum 교체
maxNum = obj[i]
// 결과 저장소에 넣기
result.push(i)
// 갯수가 바뀐 관계로 전에 갯수를 많이 맞춘 학생 제거
result.shift()
continue;
}
// 만일 맞춘 갯수가 동일할 경우 같이 저장소에 저장
else if (maxNum === obj[i]) {
result.push(i)
}
}
return result
}
이번 알고리즘의 가장 큰 어려움에 봉착된 것은 score[1][i % score[1].length]
부분이다.
초기 코드 작성 시 만일 학생 1번은 총 [1,2,3,4,5]
5개의 인덱스 밖에 없는데,
answers
배열의 인덱스가 초과되면 "어떡하지..?" 고민하며 도무지 기발한 생각이 안떠올랐다.
다행히 해당 문제를 해결할 방법은 score[1][i % score[1].length]
이였다.
let arr = [1, 2, 3, 4, 5]
요소값 1 접근 arr[5 % arr.length] === 1
요소값 2 접근 arr[6 % arr.length] === 2
요소값 2 접근 arr[11 % arr.length] === 3
%로 나머지를 구하면 인덱스를 해결할 수 있을거라고 상상도 못했다. (이마 빡! 🤦♂️ 💥)
도대체 저런 논리적 상상력은 언제 쯤 도달할 수 있을지.........
그러나 위의 코드를 다시 해석해보면 문제점이 있다.
for (let i = 2; i <= Object.keys(obj).length; i++) {
if (maxNum < obj[i]) {
maxNum = obj[i]
result.push(i)
result.shift()
continue;
}
else if (maxNum === obj[i]) {
result.push(i)
}
}
만일 [4, 4, 5] 이면 [3] 아니고 [2, 3] 이 나온다.
왜냐하면 한 번만 result.shift()
하기 때문이다....
(아니,, 어떻게 테스트 케이스 20개를 이 코드로 합격했는지 의문,,,)
다시 한번 이마 빡 x2 🤦♂️ 💥 💥
이를 보완하기 위해 다시 리펙토링하였다
function solution(answers) {
// 각 학생들 찍는 패턴을 score 배열에 저장
let score = [
[1, 2, 3, 4, 5],
[2, 1, 2, 3, 2, 4, 2, 5],
[3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
]
// 찍어서 맞춘 갯수
let count1 = 0
let count2 = 0
let count3 = 0
// 문제 채점 판별
for (let i = 0; i < answers.length; i++) {
// i % 찍는 패턴 길이로 진행하면 인덱스에 의존없이 조건이 맞아 떨어짐
if (answers[i] === score[0][i % score[0].length] ) count1++
if (answers[i] === score[1][i % score[1].length] ) count2++
if (answers[i] === score[2][i % score[2].length] ) count3++
}
// 각 맞춘 갯수들을 key값 1,2,3 번째로 나눠 할당
let obj = {1: count1, 2: count2, 3: count3}
// 맞춘 갯수 중 최댓값 할당
let maxNum = Math.max(count1, count2, count3);
let result = [];
for (let i = 1; i <= 3; i++) {
if (maxNum <= obj[i]) {
result.push(i)
}
}
}
앞의 코드보다 훨씬 깔끔해지고 Math.max(count1, count2, count3)
을 통해 문제가 해결된다.
역시 코드가 길고 억지로 푸는 경우가 있으면 문제가 일어나는 것을 새삼 다시 느낀다.
function solution(answers) {
let score = [
[1, 2, 3, 4, 5],
[2, 1, 2, 3, 2, 4, 2, 5],
[3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
]
let result = [];
score.map((item) =>
answers.filter((num, idx) =>
num === item[idx % item.length]).length)
.map((ele, idx, arr) =>
ele === Math.max(...arr) ? result.push(idx + 1) : false)
return result;
}
다른 사람이 푼 알고리즘이다.
메서드 체이닝으로 훨씬 더 간편해진 코드를 짜놓았다.
매번 느끼지만 이런 분들을 통해 더 코드를 간편하게 짤 수 있는 영감을 주시는거 같아 감사할 따름이다.