CK 007 | 상호 평가(javaScript)

This Is Empty.·2021년 8월 14일
0

codekata

목록 보기
7/35

문제

🔗 위클리 챌린지 2주차 | 상호 평가

대학 교수인 당신은, 상호평가를 통하여 학생들이 제출한 과제물에 학점을 부여하려고 합니다. 아래는 0번부터 4번까지 번호가 매겨진 5명의 학생들이 자신과 다른 학생의 과제를 평가한 점수표입니다.
...
학생들의 점수가 담긴 정수형 2차원 배열 scores가 매개변수로 주어집니다. 이때, 학생들의 학점을 구하여 하나의 문자열로 만들어서 return 하도록 solution 함수를 완성해주세요.

제한사항

  • 2 ≤ scores의 행의 길이(학생 수) ≤ 10
  • scores의 열의 길이 = scores의 행의 길이
    • 즉, scores는 행과 열의 길이가 같은 2차원 배열입니다.
  • 0 ≤ scores의 원소 ≤ 100
  • return 값 형식
    • 0번 학생의 학점부터 차례대로 이어 붙인 하나의 문자열을 return 합니다.

내가 작성한 코드


function solution(scores) {
    // 평균 담을 배열
    let answer = [];
    
    // 각 학생의 점수 배열
    let newScores = scores[0].map((_,c) => scores.map(row => row[c]));
    
    answer = newScores.map((v,i) => {
        let max = Math.max(...newScores[i])
        let min = Math.min(...newScores[i])
        let selfScore = newScores[i][i]
        
        // 유일한지 검사
        let maxLength = newScores[i].filter( (x,y) => {
            return newScores[i][y] == max
        }).length
        let minLength = newScores[i].filter( (x,y) => {
            return newScores[i][y] == min
        }).length
        
        // 자신이 평가한 점수가 유일한 최저점 또는 최고점일 경우 배열에서 삭제
        if (selfScore == min && minLength == 1) {
            newScores[i].splice(newScores[i].indexOf(selfScore), 1)
        } else if (selfScore == max && maxLength == 1) {
            newScores[i].splice(newScores[i].indexOf(selfScore), 1)
        } 
        return v.reduce((p,c) => p + c, 0) / newScores[i].length
    })
    return getGrade(answer)
}

function getGrade(score) {
    let answer = "";
    
    for(let i=0; i < score.length; i++) {
        if(score[i] >= 90) {
            answer = answer + "A"
        } else if (score[i] >= 80) {
            answer = answer + "B" 
        } else if (score[i] >= 70) {
            answer = answer + "C"
        } else if (score[i] >= 50) {
            answer = answer + "D"
        } else if (score[i] < 50) {
            answer = answer + "F"
        }
    }
    return answer
}

내가 사용한 풀이법
1. 일단 평균을 구하기 쉽게 하기위해 각 학생이 받은 점수를 한 배열로 모았다. python에서는 zip메소드로 쉽게 구현했었는데 js에서는 scores[0].map((_,c) => scores.map(row => row[c])); 와 같은 형태로 써야 한다.
2. 최고점과 최저점을 구해 각각 max, min 변수에 담은 후 그 값이 배열에서 유일한지 검사했다.
3. 그 값이 유일한 최저점이거나, 최고점이면 배열에서 삭제하고 평균을 구하고, 그렇지 않은경우는 원래 배열 그대로 평균을 구해 학점을 리턴한다.

나는 맞게 쓴 것 같은데, 몇몇 테스트케이스가 계속 오류가 났다.
알고보니 유일한지 검사하는 부분에서 자신이 평가한 점수는 최저점이고 유일한데, 최고점이 2개인경우 그 최저점을 삭제하는 일이 발생했다.
해당 오류는 아래 처럼 분리하면서 해결할 수 있었다.

  if (selfScore == min && minLength == 1) {
            newScores[i].splice(newScores[i].indexOf(selfScore), 1)
        } else if (selfScore == max && maxLength == 1) {
            newScores[i].splice(newScores[i].indexOf(selfScore), 1)
        } 
        return v.reduce((p,c) => p + c, 0) / newScores[i].length
    })
    return getGrade(answer)
}

다른 사람의 풀이

let solution = scores =>
    (scores[0].map((_, c) => scores.map(r => r[c])))
        .map((s, i) => [...s.splice(i, 1), s])
        .map(([m, s]) => Math.min(...s) <= m && m <= Math.max(...s) ? [m, ...s] : s)
        .map(s => "FDDCBAA"[Math.max(parseInt(s.reduce((a, c) => a + c) / s.length / 10) - 4, 0)])
        .join("")
function solution(scores)
{
    return scores
        .map((score,i)=>{
            return scores.map(v=>v[i])
        })
        .map((score,i)=>{
            let sum = score.reduce((a,b)=>a+b)
            let avg = sum / score.length

            let m = score.splice(i, 1)[0]

            if(m > Math.max.apply(null,score) || m < Math.min.apply(null,score)){
                sum -= m
                avg = sum / score.length
            }

            return 'FFFFFDDCBAA'[Math.floor(avg/10)]
        })
        .join('')
}
profile
Convinced myself, I seek not to convince.

0개의 댓글