문제
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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하는 값을 오름차순 정렬해주세요.
나의 풀이
function solution(answers) {
// 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]...
// 1 ~ 3의 배열 만들기
let makeArr = (pattern, arr = []) => {
for(let i = 0; i < answers.length; i++) {
arr.push(pattern[i % pattern.length]);
}
return arr;
}
let arr1 = makeArr([1, 2, 3, 4, 5]);
let arr2 = makeArr([2, 1, 2, 3, 2, 4, 2, 5]);
let arr3 = makeArr([3, 3, 1, 1, 2, 2, 4, 4, 5, 5]);
// 정답 수 세기
let result1 = arr1.reduce((acc, e, i) => acc += answers[i] === e ? 1 : 0 , 0);
let result2 = arr2.reduce((acc, e, i) => acc += answers[i] === e ? 1 : 0 , 0);
let result3 = arr3.reduce((acc, e, i) => acc += answers[i] === e ? 1 : 0 , 0);
// 가장 큰 값 반환 (여러명이면 오름차순)
let results = [result1, result2, result3];
let maxIndexs = [];
for (let i = 0; i < 3; i++) {
if (results[i] === Math.max.apply(null, results)) maxIndexs.push(i + 1);
}
return maxIndexs;
}
1,2,3의 정답 배열을 구현해놓고 요소를 하나하나 비교해주는 방법을 사용했다.
구현하지 않고 답을 비교한다면 복잡할 것 같아서 택한 방법인데, 결론만 말하자면 아니었다.
처음 문제를 보면 여러 방법이 동시에 머릿속에 떠오른다.
그 중 하나를 택해서 풀이를 시작해야 하는데,
아직 요령이 없으니 쉽게 사용할 메서드가 떠오르거나 추상이 뚜렷하게 그려지는 방법을 선택하게 된다.
하지만 막상 코드를 작성하다보면 막히는 부분이 생기고 더 복잡해지기도 하면서
잘못된 선택이라는 것을 알면서 놓지 못하는 상황이 된다.
다음 풀이부터는 떠오르는 방법을 다 기술한 뒤, 하나씩 다 풀어봐야겠다.
정확도 테스트 결과
다른 풀이
function solution(answers) {
// 맞은 갯수 셀 배열
var results = [];
var a1 = [1, 2, 3, 4, 5];
var a2 = [2, 1, 2, 3, 2, 4, 2, 5]
var a3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5];
// 배열 만들지 않고 요소 비교해서 카운트
let a1c = answers.filter((e, i) => e === a1[i % 5]).length;
let a2c = answers.filter((e, i) => e === a2[i % 8]).length;
let a3c = answers.filter((e, i) => e === a3[i % 10]).length;
let max = Math.max(a1c, a2c, a3c);
if(a1c === max) results.push(1);
if(a2c === max) results.push(2);
if(a3c === max) results.push(3);
return results;
}
배열을 만들지 않고 비교하니까 훨씬 간단했다.filter()
메서드를 이렇게 활용할 수도 있구나 하고 감탄했다.
당연히 속도도 나의 풀이보다 빠르다.
위 코드에서 주목할 점은
filter로 같은 요소로 배열을 만들고, 그 길이를 측정함으로써 갯수를 셌다는 것과
마지막에 max값을 비교할 때, 굳이 for문을 사용하지 않고 값을 일일히 비교했다는 것이다.
확장성 차원에서 보면 너무 닫힌 코드같지만, 코딩테스트는 주어진 문제를 최대한 빠르고 정확하게 해결하는 것이 목표므로
확장성 생각하면서 느리고 정확하지 않은 것보다는 저게 나은 것 같다.
하루하루 많은 것을 배워간다.
정확도 테스트 결과
'Coding test' 카테고리의 다른 글
[프로그래머스] 폰켓몬 (Level 1) - javascript (0) | 2022.04.22 |
---|---|
[프로그래머스] 로또의 최고 순위와 최저 순위 (Level 1) (0) | 2022.04.22 |
[프로그래머스] 다트 게임 (Level 1) (0) | 2022.04.21 |
[프로그래머스] 체육복 (Level 1) (0) | 2022.04.21 |
[프로그래머스] 나머지가 1이 되는 수 찾기 (Level 1) (0) | 2022.04.20 |