ALGORITHM/Programmers + α

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

Harimad 2022. 6. 14. 17:09

문제

문제 설명

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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번 학생이 몇 문제를 맞췄는지 쉽게 알 수 있었다.

%를 이용할줄 아는게 첫 번째 이번 문제의 포인트 인것 같다.

 

두 번째 포인트는 함수 마지막에 값 리턴을 어떻게 해줄 것인가?이다.

나는 문제를 어렵게 풀려고만 해서 그런지 리턴하는 코드가 깨끗하지 못하다.

하지만 다른 풀이의 리턴 방식은 깔끔하다. 내가 원하던 리턴 방식이다.

왜 이런 방식을 나는 생각해내지 못했는가? 하면서 탄식하게 되었다.

 

마지막으로, 문제를 정확하게 이해하는게 중요하다는 것을 또 한번 깨닫게 되었다.

꼭 문제를 완벽하게 이해하도록 노력하자.