반응형
문제:
스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.
이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며,
엄지손가락을 사용하는 규칙은 다음과 같습니다.

1. 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
2. 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
3. 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
4. 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
   4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.
   순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때,
   각 번호를 누른 엄지가 왼손인지 오른손인지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.

[제한사항]
  - numbers 배열의 크기는 1 이상 1,000 이하입니다.
  - numbers 배열 원소의 값은 0 이상 9 이하인 정수입니다.
  - hand는 "left" 또는 "right" 입니다.
     : "left"는 왼손잡이, "right"는 오른손잡이를 의미합니다.
  - 왼손 엄지를 사용한 경우는 L, 오른손 엄지를 사용한 경우는 R을 순서대로 이어붙여 문자열 형태로 return 해주세요.

 

문제 풀어보기: https://school.programmers.co.kr/learn/courses/30/lessons/67256

 

풀이보기
더보기
function solution(numbers, hand) {
    const keypad = [[1, 2, 3], [4, 5, 6], [7, 8, 9], ['*', 0, '#']];
    let left = [3, 0];
    let right = [3, 2];
    let result = [];
    
    for(let i = 0; i < numbers.length; i++) {
        for(let j = 0; j < keypad.length; j++) {
            for(let k = 0; k < keypad[j].length; k++) {
                // 입력할 번호와 키패드 번호가 일치할 시
                if(numbers[i] === keypad[j][k]) {
                    // 왼쪽 열일 때
                    if([1, 4, 7].includes(numbers[i])) {
                       left = [j, k];
                       result.push('L');
                    } 
                    // 오른쪽 열일 때
                    else if([3, 6, 9].includes(numbers[i])) {
                       right = [j, k];
                       result.push('R');
                    } 
                    // 가운데 열일 때
                    else {
                       // 각 왼손과 오른손으로 눌렀을 때의 거리 계산
                       let leftCount = Math.abs(j - left[0]) + Math.abs(k - left[1]);
                       let rightCount = Math.abs(j - right[0]) + Math.abs(k - right[1]);
                       
                       // 오른손이 더 가까울 경우
                       if(leftCount > rightCount) {
                           right = [j, k];
                           result.push('R');
                        } 
                        // 왼손이 더 가까울 경우
                        else if(rightCount > leftCount) {
                           left = [j, k];
                           result.push('L');
                        } 
                        // 거리가 같을 경우
                        else {
                           // hand에 따라 결정
                           if(hand === 'right') {
                               right = [j, k];
                               result.push('R');
                           } else {
                               left = [j, k];
                               result.push('L');
                           }
                        }
                    }
                }
            }
        }
    }
    
    return result.join('');
}

코드가 복잡해보이지만 막상 그렇지는 않다.

나는 좌표를 생각하면서 문제를 풀었다.

먼저 키패드와 비슷한 모양의 배열을 만들어주고, 시작위치는 *, # 이므로 해당 인덱스를 left, right에 각각 저장한다.

 

그 다음 누를 번호와 키패드의 번호가 같을 경우,

number[i]가 1, 4, 7 중 하나이면 왼손, 3, 6, 9 중 하나면 오른손이므로 키패드의 인덱스를 해당하는 손에 저장한다.

또한 result에 해당하는 손을 push 해준다.

left, right에 인덱스를 저렇게 저장하는 이유는 당연히 계속해서 값을 덮어씌워야 하기 때문이다.

 

그리고 가운데 열의 숫자일 때는 왼손에서의 거리, 오른손에서의 거리를 각각 계산해서 저장한다.

이 값을 가지고 leftCount가 더 크다면 오른손, rightCount가 더 크다면 왼손을 저장하도록 한다.

만약 두 손의 거리가 같을 경우에는 주어진 hand를 기준으로 해당하는 값을 저장하면 된다.

 

이렇게 result에 저장된 값은 배열이므로 join을 통해 문자열로 반환해주면 끝이다!

 

반응형
반응형
문제:
수많은 마라톤 선수들이 마라톤에 참여하였습니다.
단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때,
완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

제한사항
  - 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
  - completion의 길이는 participant의 길이보다 1 작습니다.
  - 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  - 참가자 중에는 동명이인이 있을 수 있습니다.

 

문제 풀어보기: https://school.programmers.co.kr/learn/courses/30/lessons/42576#

 

풀이보기
더보기
function solution(participant, completion) {
    let count = {};
    
    for(let name of participant) {
        count[name] = (count[name] || 0) + 1;
    }
    
    for(let name of completion) {
        count[name]--;
    }
    
    for(let name in count) {
        if(count[name] > 0) return name;
    }
}

효율성을 따져야하는 문제이기 때문에 객체를 택했다.

먼저 count 객체에 참가자의 이름과 count를 저장해준다.

{ a: 1, b: 1, ... } 이런식으로 저장되고,

그 다음 완주자 목록을 통해 count 객체에서 참가자 이름에 해당하는 값은 감소 시켜준다.

그러면 이제 완주하지 못한 사람만 1이 남아있을 것이다.

그렇기 때문에 count를 순회하며 0이상인 선수의 이름을 리턴하면 끝!

 

반응형
반응형
문제:
로또를 구매한 민우는 당첨 번호 발표일을 학수고대하고 있었습니다.
하지만, 민우의 동생이 로또에 낙서를 하여, 일부 번호를 알아볼 수 없게 되었습니다.
당첨 번호 발표 후, 민우는 자신이 구매했던 로또로 당첨이 가능했던 최고 순위와 최저 순위를 알아보고 싶어 졌습니다.

알아볼 수 없는 번호를 0으로 표기하기로 하고, 민우가 구매한 로또 번호 6개가 44, 1, 0, 0, 31 25라고 가정해보겠습니다.
당첨 번호 6개가 31, 10, 45, 1, 6, 19라면, 당첨 가능한 최고 순위와 최저 순위의 한 예는 아래와 같습니다.

순서와 상관없이, 구매한 로또에 당첨 번호와 일치하는 번호가 있으면 맞힌 걸로 인정됩니다.
알아볼 수 없는 두 개의 번호를 각각 10, 6이라고 가정하면 3등에 당첨될 수 있습니다.
3등을 만드는 다른 방법들도 존재합니다. 하지만, 2등 이상으로 만드는 것은 불가능합니다.
알아볼 수 없는 두 개의 번호를 각각 11, 7이라고 가정하면 5등에 당첨될 수 있습니다.
5등을 만드는 다른 방법들도 존재합니다. 하지만, 6등(낙첨)으로 만드는 것은 불가능합니다.

민우가 구매한 로또 번호를 담은 배열 lottos, 당첨 번호를 담은 배열 win_nums가 매개변수로 주어집니다. 이때, 당첨 가능한 최고 순위와 최저 순위를 차례대로 배열에 담아서 return 하도록 solution 함수를 완성해주세요.

 

문제 풀어보기: https://school.programmers.co.kr/learn/courses/30/lessons/77484#fn1

 

풀이보기
더보기
function solution(lottos, win_nums) {
    let scoreToRank = {
        6: 1,
        5: 2,
        4: 3,
        3: 4,
        2: 5,
        1: 6,
        0: 6
};
    
    let current = lottos.filter((num) => win_nums.includes(num)).length;
    let zero = lottos.filter((num) => num === 0).length;

    return [scoreToRank[current + zero], scoreToRank[current]];
}

로또 당첨번호와 일치하는 개수를 current에 저장하고, 알아볼 수 없는 번호의 개수를 zero에 저장해줬다.

맞춘 개수에 맞는 등수를 저장한 rank 객체를 이용해서

최고 순위는 current + zero로, 최저 순위는 current를 이용해서 구해주면 된다.

 

배열로 등수를 저장해서 풀 수도 있다!

function solution(lottos, win_nums) {
    let rank = [6, 6, 5, 4, 3, 2, 1]
    
    let current = lottos.filter((num) => win_nums.includes(num)).length;
    let zero = lottos.filter((num) => num === 0).length;

    return [rank[current + zero], rank[current]];
}

0, 1개는 6등, 1개를 맞추면 5등 이런 식이기 때문에 배열의 인덱스를 활용해서 풀 수도 있었다.

 

반응형
반응형

 

클로저(Closure)란?

    “클로저는 함수가 외부의 변수에 접근할 수 있는 기능”이다.

     즉, 내부 함수가 외부 함수의 변수에 접근하고 기억하는 것이 클로저이다.


예제 코드로 살펴보기 🔍
function outer() {
    let count = 0; // 외부 함수의 지역 변수

    return function inner() {
        count++;
        console.log(`현재 count는 ${count}입니다.`);
    };
}

const counter = outer(); // outer는 실행되고, inner가 반환됨
counter(); // 현재 count는 1입니다.
counter(); // 현재 count는 2입니다.

 

겉으로만 봤을 때는 counter를 실행하면 count가 각각 1, 1로 출력될 것 같지만 실제로는 아니다.

outer() 함수는 실행되고 사라졌지만,그 안에서 만든 inner() 함수는 count를 기억하고 있다.

왜냐하면 count가 클로저에 포함되어서 메모리에 살아있기 때문이다.


클로저의 핵심 구성
구성 요소 설명
외부 함수 (outer) 지역 변수를 선언하는 함수
내부 함수 (inner) 외부 함수의 지역 변수에 접근하는 함수
반환 내부 함수가 외부로 반환되어 사용됨
기억 외부 함수의 지역 변수를 내부 함수가 기억 (→ 클로저)

그렇다면 클로저를 왜 쓰는걸까?

 

    1. 데이터 보호 / 은닉 (캡슐화): 외부에서 직접 접근 못하게 하고, 함수로만 조작하도록 할 수 있음.

function createCounter() {
    let count = 0;
    return {
        increment() { count++; return count; },
        decrement() { count--; return count; },
    };
}

const counter = createCounter();
counter.increment(); // 1
counter.decrement(); // 0
// count에 직접 접근은 불가능

 

    2. 상태 유지:  클로저를 사용하면 상태를 기억하게 할 수 있음.

    3. 콜백, 이벤트 핸들러:  비동기 처리에서도 클로저가 유용하게 쓰임.

 

 

[주의할 점]
1) 메모리 누수: 클로저로 인해 변수가 해제되지 않고 남아있으면 메모리 낭비가 발생할 수 있다.
2) 남용 주의: 모든 함수에 클로저를 만들 필요는 없고, 필요한 상황에서만 쓰는 게 좋다.

 

요약

 

    1) 클로저는 내부 함수가 외부 함수의 변수에 접근할 수 있게 해주는 기능

    2) 함수가 자신이 만들어질 때의 환경을 기억

    3) 상태 유지, 캡슐화, 비동기 처리 등에 매우 유용

    4) 하지만 메모리 관리에는 주의해야 함

 

반응형
반응형
문제:
자연수 n이 주어졌을 때, n의 다음 큰 숫자는 다음과 같이 정의 합니다.
  - 조건 1. n의 다음 큰 숫자는 n보다 큰 자연수 입니다.
  - 조건 2. n의 다음 큰 숫자와 n은 2진수로 변환했을 때 1의 갯수가 같습니다.
  - 조건 3. n의 다음 큰 숫자는 조건 1, 2를 만족하는 수 중 가장 작은 수 입니다.
예를 들어서 78(1001110)의 다음 큰 숫자는 83(1010011)입니다.
자연수 n이 매개변수로 주어질 때, n의 다음 큰 숫자를 return 하는 solution 함수를 완성해주세요.

 

문제 풀어보기: https://school.programmers.co.kr/learn/courses/30/lessons/12911

 

풀이보기
더보기
function solution(n) {
    let transCount = n.toString(2).match(/1/g).length;
    
    while(n++) {
        let iTransCount = n.toString(2).match(/1/g).length;
        if(transCount === iTransCount) return n;
    }
}

조건 1은 n++로 충족시킬 수 있고,

조건 2의 경우 미리 n을 2진수로 변환시켜서 1의 길이를 transCount에 저장해둔다.

그리고 while문 안에서 n++ 값을 똑같이 2진수 변환 후 1 길이를 저장하고,

만약 count가 같다면 해당 n을 리턴하도록 한다.

여기서 n은 순차적으로 증가하므로 자연스럽게 조건 3도 충족하게 된다.

 

반응형
반응형
문제:
명함 지갑을 만드는 회사에서 지갑의 크기를 정하려고 합니다.
다양한 모양과 크기의 명함들을 모두 수납할 수 있으면서, 작아서 들고 다니기 편한 지갑을 만들어야 합니다.
이러한 요건을 만족하는 지갑을 만들기 위해 디자인팀은 모든 명함의 가로 길이와 세로 길이를 조사했습니다.
아래 표는 4가지 명함의 가로 길이와 세로 길이를 나타냅니다.

명함 번호 가로 세로
1 60 50
2 30 70
3 60 30
4 80 40

가장 긴 가로와 세로가 각각 80, 70이기 때문에 80(가로) x 70(세로) 크기의 지갑을 만들면모든 명함들을 수납할 수 있습니다.
하지만 2번 명함을 가로로 눕혀 수납한다면 80(가로) x 50(세로) 크기의 지갑으로 모든 명함들을 수납할 수 있습니다.
이때의 지갑 크기는 4000(=80 x 50)입니다.
모든 명함의 가로 길이와 세로 길이를 나타내는 2차원 배열 sizes가 매개변수로 주어집니다.
모든 명함을 수납할 수 있는 가장 작은 지갑을 만들 때, 지갑의 크기를 return 하도록 solution 함수를 완성해주세요.

 

문제 풀어보기: https://school.programmers.co.kr/learn/courses/30/lessons/86491

 

풀이보기
더보기
function solution(sizes) {
    let result = { max: [], min: [] };
    
    for(let i = 0; i < sizes.length; i++) {
        result.max.push(Math.max(...sizes[i]));
        result.min.push(Math.min(...sizes[i]));
    }
    
    return Math.max(...result.max) * Math.max(...result.min);
}

오늘은 간단한 문제를 풀어보았다!

최소 직사각형이므로 가로, 세로 길이에서 큰 수와 작은 수를 각각 max, min에 저장하고,

마지막에 max에서 가장 큰수, min에서 가장 큰 수를 곱해주면 된다!

 

반응형
반응형
문제:
카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다.
다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다.
다트 게임의 점수 계산 로직은 아래와 같다.

1. 다트 게임은 총 3번의 기회로 구성된다.
2. 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.
3. 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고,
     각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.
4. 옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다.
     아차상(#) 당첨 시 해당 점수는 마이너스된다.
5. 스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다.
6. 스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다.
7. 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다.
8. Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.
9. 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.

0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

입력 형식
"점수|보너스|[옵션]"으로 이루어진 문자열 3세트. 예) 1S2D*3T
  - 점수는 0에서 10 사이의 정수이다.
  - 보너스는 S, D, T 중 하나이다.
  - 옵선은 *이나 # 중 하나이며, 없을 수도 있다.

출력 형식
3번의 기회에서 얻은 점수 합계에 해당하는 정수값을 출력한다. 예) 37

 

문제 풀어보기: https://school.programmers.co.kr/learn/courses/30/lessons/17682

 

풀이보기
더보기
function solution(dartResult) {
    let scores = dartResult.match(/\d+\D+/g);
    scores.forEach((score, i) => {
        scores[i] = [
            ...(score.match(/\d+/) || []),
            ...(score.match(/[a-zA-Z]+/) || []),
            ...(score.match(/[^a-zA-Z0-9]+/) || [])]});

    for(let i = 0; i < scores.length; i++) {
        let score = 0;
        
        if(scores[i][1] === 'S') {
            score = Math.pow(scores[i][0], 1);
        } else if(scores[i][1] === 'D') {
            score = Math.pow(scores[i][0], 2);
        } else if(scores[i][1] === 'T') {
            score = Math.pow(scores[i][0], 3);
        }
        
        if(scores[i][2] === '*') {
            if((i - 1) >= 0) {
                scores[i - 1] *= 2;
                score *= 2;
            } else {
                score *= 2;
            }
        } else if(scores[i][2] === '#') {
            score *= -1;
        }
        scores[i] = score;
    }
    
    return scores.reduce((total, current) => total + current, 0);
}

처음 푼 풀이이다.

문제를 보고 먼저 각 기회에 맞게 배열로 나눈 뒤, 또 그 요소를 점수, 보너스, 옵션으로 나눠야겠다는 생각을 했다.

그래서 정규식을 이용하여 각각 나누어주었다.

 

 그 다음 보너스를 확인하여 알맞게 점수를 제곱해주었고, 옵션에 따라 점수를 곱해주었다.

마지막으로 각 점수들을 더해서 반환해주면 끝이다!

 

하지만 뭔가 마음에 들지 않았다. 너무 하드 코딩한 느낌이랄까 ... 

그래서 수정한다고 해봤는데 그리 크게 수정하지는 못했다.

function solution(dartResult) {
    let bonus = {'S': 1, 'D': 2, 'T': 3};
    let scores = dartResult.match(/\d+\D+/g);
    scores.forEach((score, i) => {
        scores[i] = [
            ...(score.match(/\d+/) || []),
            ...(score.match(/[a-zA-Z]+/) || []),
            ...(score.match(/[^a-zA-Z0-9]+/) || [])]});

    for(let i = 0; i < scores.length; i++) {
        let score = Math.pow(scores[i][0], bonus[scores[i][1]]);
        
        if(scores[i][2] === '*') {
            score *= 2;
            if((i - 1) >= 0) {
                scores[i - 1] *= 2;
            }
        } else if(scores[i][2] === '#') {
            score *= -1;
        }
        scores[i] = score;
    }
    
    return scores.reduce((total, current) => total + current, 0);
}

수정한건 두가지인데, 먼저 보너스 점수를 미리 선언해두니 중복 코드를 줄일 수 있었다. ㅎㅎ .. 

그 다음 옵션을 계산할 때 스타상은 어차피 해당 점수의 2배를 해줘야하므로 else문은 삭제해도 됐었다.

 

for문만 보면 그래도 깔끔해지긴 했지만 정규식 부분이 여전히 마음에 들지 않았다.

아직 정규식을 공부해보지는 않아서 더 나은 방법을 알 수가 없었기 때문에 gpt의 힘을 빌렸다 ㅎㅎ ;

 

function solution(dartResult) {
    const regex = /(\d+)([SDT])([*#]?)/g;
    let bonus = {'S': 1, 'D': 2, 'T': 3};
    let scores = [];
    let match;

    while ((match = regex.exec(dartResult)) !== null) {
        let [_, num, b, opt] = match;
        let score = Math.pow(parseInt(num), bonus[b]);

        if (opt === '*') {
            score *= 2;
            if (scores.length > 0) {
                scores[scores.length - 1] *= 2;
            }
        } else if (opt === '#') {
            score *= -1;
        }

        scores.push(score);
    }
    
    return scores.reduce((total, current) => total + current, 0);
}

먼저 정규식을 선언해두고 while 문을 이용해서 풀었다.

엄청 생소한 메서드들이었는데 여기서도 특히 match 값을 왜 while 조건문 안에서 저장해주는지 의문이었다.

그 이유는 regex.exec()는 g 플래그와 함께 쓰면 매번 한 개씩 매치를 반환해주기 때문이었다.

만약 미리 match에 저장해둔다면 반복이 한 번밖에 되지 않기 때문에 원하는 답이 안나온다.

 

그리고 match 값을 각각 구조 분해하여 num, b, opt에 저장해주고 나면 나머지 코드는 비슷하다.

여기서 또 궁금했던건 왜 굳이 [_, num, b, opt]에서 처음 요소를 비워주는지 궁금했다.

그 이유는 exec의 반환 값을 보면 알 수 있었다.

let [_, num, b, opt] = match;
// _ : 전체 매치 (예: "1S")
// num : 숫자 (예: "1")
// b : 보너스 (예: "S")
// opt : 옵션 (예: "*", "#", 또는 "")

이런 식으로 결과가 나오기 때문에 현재 문제에서는 전체 매치 값은 필요없으므로 비워줬던 것이다.

 

이 문제는 정규식을 잘 안다면 쉽게 풀 수 있는 문제인 것 같다.

 

반응형
반응형
문제:
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다.
수포자는 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://school.programmers.co.kr/learn/courses/30/lessons/42840

 

풀이보기
더보기
function score(userAnswers, answers) {
  let count = 0;

  for (let i = 0; i < answers.length; i++) {
    let index = i % userAnswers.length;
    if (answers[i] === userAnswers[index]) count++;
  }

  return count;
}

function solution(answers) {
  let student1 = [1, 2, 3, 4, 5];
  let student2 = [2, 1, 2, 3, 2, 4, 2, 5];
  let student3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5];

  let corretCounts = [];

  corretCounts.push(score(student1, answers));
  corretCounts.push(score(student2, answers));
  corretCounts.push(score(student3, answers));

  let maxCount = Math.max(...corretCounts);
  let topScorers = [];

  for (let i = 0; i < corretCounts.length; i++) {
    if (maxCount === corretCounts[i]) topScorers.push(i + 1);
  }

  return topScorers;
}

 처음에는 반복되는 코드인 맞은 문제 수를 리턴해주는 score 함수를 따로 만들어서 풀었다.

학생마다 찍는 방식을 미리 선언해주고 score 함수를 통해 얻은 count를 correctCounts에 저장해준다.

그 후 correctCounts에서의 최댓값을 구해서 maxCount에 넣어주고,

문제를 많이 맞춘 학생의 번호를 topScores에 넣어줄 것이다.

그리고 maxCount와 correctCounts[i]가 같다면 topScore에 i + 1을 푸쉬하고,

마지막으로 topScores를 리턴해주면 된다.

 

그리고 다른 사람 풀이를 보다가 생각도 못했던 filter를 쓰는 방법도 있어서 filter로도 풀어봤다.

function solution(answers) {
    let student1 = [1, 2, 3, 4, 5];
    let student2 = [2, 1, 2, 3, 2, 4, 2, 5];
    let student3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5];
    
    let correctCount1 = answers.filter((answer, i) => answer === student1[i % student1.length]).length;
    let correctCount2 = answers.filter((answer, i) => answer === student2[i % student2.length]).length;
    let correctCount3 = answers.filter((answer, i) => answer === student3[i % student3.length]).length;
    
    let maxCount = Math.max(correctCount1, correctCount2, correctCount3);
    let result = [];
    
    if(maxCount === correctCount1) result.push(1);
    if(maxCount === correctCount2) result.push(2);
    if(maxCount === correctCount3) result.push(3);
    
    return result;
}

이 문제는 다양하게 풀이할 수 있어서 좋은 것 같다!

 

반응형

+ Recent posts