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

JINSUNG LEE·2021년 6월 30일
0
post-thumbnail


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;
}

다른 사람이 푼 알고리즘이다.

메서드 체이닝으로 훨씬 더 간편해진 코드를 짜놓았다.

매번 느끼지만 이런 분들을 통해 더 코드를 간편하게 짤 수 있는 영감을 주시는거 같아 감사할 따름이다.

profile
https://californialuv.github.io/Tech_Blog 이사 갔어용 🌎 🚀

0개의 댓글