코딩 테스트/프로그래머스(LV1)

[프로그래머스] 모의고사 (LV1 - JavaScript)

dev-hpk 2024. 9. 25. 17:48

https://school.programmers.co.kr/learn/courses/30/lessons/42840

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

1. 문제

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

 

2. 정답 풀이

풀이 전략

  • 정답과 유저들의 찍기 전략을 비교해 정답 개수(length)를 result 배열에 담아 리턴한다.
  • Math.max() 메서드를 이용해 최대 정답 개수를 구한다. (최다 득점자가 여럿일 경우가 있기 때문에 sort()로 정렬하지 않고 최대값 구해서 계산)
  • 정답 개수 배열을 순회하며 최다 득점자인 경우 answer 배열에 수포자(index+1 : 배열의 인덱스는 0부터 시작하기 때문에 +1) 추가
const gradeUserAnswer = (answers, users) => {
    const result = users.map(user => { // result : 맞힌 문제의 수를 담는 배열
        return answers.filter((answer, i) => {
            return answer === user[i % user.length]; // 맞힌 문제만 필터링
        }).length // 맞힌 문제의 수를 리턴
    })
    
    return result;
}

function solution(answers) {
    const answer = [];
    const users = [
        [1,2,3,4,5],
        [2,1,2,3,2,4,2,5],
        [3,3,1,1,2,2,4,4,5,5]
    ];
    const arrUserCorrect = gradeUserAnswer(answers, users);
    
    arrUserCorrect.forEach((grade, index) => {
        if(grade === Math.max(...arrUserCorrect)) {
            answer.push(index+1) // 최다 득점자인 경우 answer에 인덱스 추가
        }
    })
    
    return answer;
}

 

3. 다른 사람 풀이

function solution(answers) {
    const answer = [];
    const a1 = [1, 2, 3, 4, 5];
    const a2 = [2, 1, 2, 3, 2, 4, 2, 5]
    const a3 = [ 3, 3, 1, 1, 2, 2, 4, 4, 5, 5];

    const a1c = answers.filter((a,i)=> a === a1[i%a1.length]).length;
    const a2c = answers.filter((a,i)=> a === a2[i%a2.length]).length;
    const a3c = answers.filter((a,i)=> a === a3[i%a3.length]).length;
    const 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;
}

 

 

 

 

코드를 최대한 간결하고 가독성 있게 작성하려고 노력하며 문제를 풀었다. 그런데 다른 사람들의 풀이를 보니, 내 코드는 가독성이 다소 떨어지는 것 같다...😅
재사용성과 유지보수를 고려해 getUserAnswer 로직을 분리하고 solution에서 호출하도록 했는데, 직관적이고 간결한 코드가 더 나은 걸까...?