Practice for coding test

프로그래머스 - Level 1. 로또의 최고 순위와 최저 순위 / JavaScript (js)

Gray Park 2023. 2. 18. 11:30
728x90
반응형

문제설명

문제분석 - 수도코드

이 문제는 로또 당첨번호 중 N개의 번호를 확인할 수 없는 상태라는 전제 조건이 있습니다. 이 상황에서 이번주 당첨번호가 주어졌을 때, 가장 희망적인 경우와 그 반대의 경우의 당첨등수를 확인하는 문제입니다. 저 같아도 알아볼 수 없는 번호가 있다면, 이런 희망회로를 돌리면서 잠시나마 즐거운 상상을 할 것 같긴 합니다. 충분히 공감되는 김에 문제를 후딱 해결하도록 하겠습니다.

  1. 먼저 민우가 가지고 있는 로또 용지에서 번호를 확인할 수 없는 0으로 된 요소의 갯수를 기록한다.
  2. 민우의 로또용지를 순회하며 각 번호가 당첨번호인지 확인한다.
  3. 민우의 로또용지에서 당첨번호의 갯수와 알아볼 수 없는 번호를 더해 가장 높은 등수를 구한다.
  4. 민우의 로또용지에서 당첨번호의 갯수만으로 가장 낮은 등수를 구한다.

문제를 단순화 했으니 이해하기 쉽게 코드를 짜보겠습니다.

이해하기 쉽게 코드작성하기

function solution(lottos, win_nums) {
	// 정렬
	lottos = lottos.sort((a,b)=>a-b);
	// 알아볼 수 없는 숫자의 갯수
    const count = lottos.filter(x => x === 0).length;
    // 당첨번호 중 민우의 용지에 있는 번호를 true로 변환
    const usedNums = new Array(win_nums.length).fill(false);
    const winNum = [];
    lottos.forEach(x => {
        const idx = win_nums.indexOf(x);
        if(idx !== -1) {
            winNum.push(x);
            usedNums[idx] = true;
        }
    });
    // 당첨된 숫자의 갯수
    const usedNumLength = usedNums.filter(x => x).length;
    const max = getRank(usedNumLength + count);
    const min = getRank(usedNumLength);
    return [max, min];
}

// 등수 확인
function getRank(num) {
    return num === 6 ? 1
        : num === 5 ? 2
        : num === 4 ? 3
        : num === 3 ? 4
        : num === 2 ? 5
        : 6;
}

코드를 작성하고 나니 불필요한 코드가 많습니다. 먼저 1) 정렬이 필요가 없고, 2) winNum 배열이 사용되지 않습니다. 따라서 다음과같이 코드를 개선할 수 있습니다.

function solution(lottos, win_nums) {
    const count = lottos.filter(x => x === 0).length;
    const usedNums = new Array(win_nums.length).fill(false);
    lottos.forEach(x => {
        const idx = win_nums.indexOf(x);
        if(idx !== -1) {
            usedNums[idx] = true;
        }
    });
    const usedNumLength = usedNums.filter(x => x).length;
    const max = getRank(usedNumLength + count);
    const min = getRank(usedNumLength);
    return [max, min];
}

function getRank(num) {
    return num === 6 ? 1
        : num === 5 ? 2
        : num === 4 ? 3
        : num === 3 ? 4
        : num === 2 ? 5
        : 6;
}

막상 이렇게 해놓고 보니 usedNums와 forEach를 reduce로 합칠 수 있을 것 같습니다. 하는김에 코드도 좀 깔끔하게 맞추고, 변수 이름도 변경해보겠습니다.

function solution(lottos, win_nums) {
    const canNotFindNumberCount = lottos.filter(x => x === 0).length;
    const winCount = lottos
        .reduce((a, c) => {
            const idx = win_nums.indexOf(c);
            if(idx > -1) a[idx] = true;
            return a;
        }, new Array(win_nums.length).fill(false))
        .filter(x => x)
        .length;

    return [getRank(winCount + canNotFindNumberCount), getRank(winCount)];
}

function getRank(num) {
    return num === 6 ? 1
        : num === 5 ? 2
        : num === 4 ? 3
        : num === 3 ? 4
        : num === 2 ? 5
        : 6;
}

이렇게 변환하면 별다른 주석없이도 코드를 읽을 수 있겠습니다. 이 문제를 제외하면 Level 1 문제가 4문제밖에 안남았습니다. Level 2, 3도 꾸준히 작성할 수 있길 바라며 오늘의 포스팅 마칩니다.

728x90
반응형