모의고사(Javascript)

·2022년 9월 27일
0
post-thumbnail

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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하는 값을 오름차순 정렬해주세요.

입출력 예

answersreturn
[1,2,3,4,5][1]
[1,3,2,4,2][1,2,3]

입출력 예 설명

입출력 예 #1

수포자 1은 모든 문제를 맞혔습니다.
수포자 2는 모든 문제를 틀렸습니다.
수포자 3은 모든 문제를 틀렸습니다.
따라서 가장 문제를 많이 맞힌 사람은 수포자 1입니다.

입출력 예 #2

모든 사람이 2문제씩을 맞췄습니다.

나의 풀이

function solution(answers) {

    let one = '12345'.repeat(answers.length).split('').map(v => v*1);
    let two = '21232425'.repeat(answers.length).split('').map(v => v*1);
    let three ='3311224455'.repeat(answers.length).split('').map(v => v*1);

    let corr1 = answers.filter((v,i)=> v === one[i]).length;
    let corr2 = answers.filter((v,i)=> v === two[i]).length;
    let corr3 = answers.filter((v,i)=> v === three[i]).length;

    let correct = [corr1, corr2, corr3];

    return [1,2,3].filter((v,i) => correct[i] === Math.max(...correct))
}

반복되는 부분이 너무 많아서 함수로 바꿨었는데, 함수 내부에서 함수를 호출하니 성능 문제가 생겨서 다시 원래 나열한 모양대로 다시 바꾸어줬다.

//원래 코드     
	let one = '12345'.repeat(answers.length).split('').map(v => v*1);
    let two = '21232425'.repeat(answers.length).split('').map(v => v*1);
    let three ='3311224455'.repeat(answers.length).split('').map(v => v*1);

//바꿔준 코드
   function answer(num) {
        return num.repeat(answers.length).split('').map (v => v * 1)

이것만 수정해도 문제를 통과할 수 있었다. 다만 불필요한 반복을 너무 많이 하는데다가, repeat함수를 쓰려고 문자열로 만들었다가 나누고 숫자 형태로 만들어주는 식이 너무 복잡하다는 생각이 들었다.

참고할 풀이 1

function solution(answers) {
    var answer = [];
    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];

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

푸는 방식은 비슷한데, 나는 처음에 반복되는 패턴 자체를 여러번 만들어서 비교해줬다면 이 풀이에서는 나머지를 이용해서 값을 filter했다. 반복되는 패턴이라면 길이로 나눴을 때 나머지가 같은 수는 똑같은 값을 인출하기 때문이다.

참고할 풀이 2

function solution(answers) {
    var answer = [];
    const man1 = [1, 2, 3, 4, 5];
    const man2 = [2, 1, 2, 3, 2, 4, 2, 5];
    const man3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5];
    let count = [0, 0, 0];

    for(let i = 0; i < answers.length; i++) {
        if(answers[i] == man1[i % man1.length]) count[0]++;
        if(answers[i] == man2[i % man2.length]) count[1]++;
        if(answers[i] == man3[i % man3.length]) count[2]++;
    }

    const max = Math.max(count[0], count[1], count[2]);
    for(let i = 0; i < count.length; i++) {
        if(max == count[i]) answer.push(i + 1);
    }

    return

제일 잘 짰다고 생각하는 코드이다. 나는 정답 문항 배열을 만든 후에 그 길이를 재 줬는데 정답 개수만 count 변수에 할당해서 주었다. 그리고count[0],[1],[2]에 넣어서 바로 배열에 값을 넣어 주었다. 판별하는 방식은 위의 풀이와 같게 나머지를 이용하여 판별해 주었다. 마지막은 반복문으로 맞힌 수가 가장 많은 사람의 번호를 인출해 줬는데, index+1을 answer 배열에 push해서 마지막 최대 점수 배열에 넣어주었다. 반복도 적고 성능이 잘 나올 것 같다.

profile
전 이것도 몰라요

0개의 댓글

관련 채용 정보