로또의 최고 순위와 최저 순위

Sheryl Yun·2023년 8월 5일
0

문제 링크

처음 풀이

  • 일치하는 숫자 갯수를 가지고 최저, 최고 순위를 구할 수 있음
  • 0은 최고일 경우 win 숫자와 모두 일치, 최저일 경우 win 숫자와 모두 불일치
  • 모두 0일 수도, 0이 하나도 없을 수도 있음
  • 로또 숫자 전체 길이는 무조건 6자리 => LOTTO_LEN으로 상수화
function solution(lottos, win_nums) {
    let answer = [];
    let max = 0;
    let min = 0;
    const LOTTO_LEN = 6;
    
    for (let i = 0; i < LOTTO_LEN; i++) {
        if (win_nums.includes(lottos[i])) min++;
        if (lottos[i] === 0) max++;
    }
    
    max += min;
    
    const stLen = LOTTO_LEN + 1; // 7
    
    answer.push(
        max === 0 ? stLen - 1 : stLen - max, 
        min === 0 ? stLen - 1 : stLen - min
    );
    
    return answer;
}

처음에 푼 코드는 답은 나왔지만 약간 정신이 없어서 코드를 개선해보기로 했다.

개선 과정

  • 우선 for-i문은 순서가 중요하지 않은 로직이기 때문에 for-of로 축소하려다가 생각해보니 조건에 일치하는 값을 찾는 것이라 filter로 바꿔주었다.

  • for문 끝나고 어정쩡하게 있던 max += min 라인은 max 뒤에 min을 더해줘서 생략했다.

function solution(lottos, win_nums) {
    let answer = [];
    let max = 0;
    let min = 0;
    const LOTTO_LEN = 6;
    
    min = lottos.filter((lotto) => win_nums.includes(lotto)).length;
    max = lottos.filter((lotto) => !lotto).length + min;
    
    const stLen = LOTTO_LEN + 1; // 7
    
    answer.push(
    	max === 0 ? stLen - 1 : stLen - max, 
        min === 0 ? stLen - 1 : stLen - min
    );
    
    return answer;
}
  • 길어보이는 === 0부분을 !로 줄이니 눈에 들어오는 코드가 간결해져서 더 축소할 수 있는 부분이 보였다.
  • 뒤에 겹치는 stLen을 앞으로 빼고 마이너스되는 요소를 구하는 부분에만 삼항 연산자를 붙였다.
function solution(lottos, win_nums) {
    let answer = [];
    let max = 0;
    let min = 0;
    const LOTTO_LEN = 6;
    
    min = lottos.filter((lotto) => win_nums.includes(lotto)).length;
    max = lottos.filter((lotto) => !lotto).length + min;
    
    const stLen = LOTTO_LEN + 1; // 7
    
    answer.push(
        stLen - (!max ? 1 : max),
        stLen - (!min ? 1 : min),
    );
    
    return answer;
}
  • stLen 선언을 위로 올리니 LOTTO_LEN 상수가 stLen 계산 한번에만 쓰이는 게 보였다.
  • stLen을 STANDARD_LEN으로 상수화하고 LOTTO_LEN를 삭제했다.
  • 이번 순위의 규칙은 7 - 일치하는 숫자 갯수였다. STANDARD_LEN을 그냥 7로 적으면 어디서 나온 7인지 알 수 없기 때문에 lottos 길이에 +1 한 것임을 명시했다.
function solution(lottos, win_nums) {
    let answer = [];
    let min = lottos.filter((lotto) => win_nums.includes(lotto)).length;
    let max = lottos.filter((lotto) => !lotto).length + min;
    const STANDARD_LEN = lottos.length + 1;
    
    answer.push(
        STANDARD_LEN - (!max ? 1 : max),
        STANDARD_LEN - (!min ? 1 : min),
    );
    
    return answer;
}

총 22줄을 13줄로 줄이는 데 성공

선언한 변수들을 answer.push에 모두 때려넣으면 이것보다 더 줄일 수 있겠지만 가독성을 위해서 여기까지만 진행했다.

새로운 풀이

  • 총 11줄의 코드이다.
  • 순위 구하는 데 배열의 index를 떠올리긴 했지만 이렇게 반환하는 방법은 떠올리지 못했다..
  • 근데 [6, 6, ..] 부분이 약간 하드코딩 느낌 나고 배열이 조금만 더 길어지면 일일이 치기 힘들 것 같다는 생각이
  • filter의 v 부분이 더 구체적인 네이밍이었다면 가독성에 좀 더 좋지 않았을까 하는 생각을 해봤다.
function solution(lottos, win_nums) {
    const rank = [6, 6, 5, 4, 3, 2, 1];

    let minCount = lottos.filter(v => win_nums.includes(v)).length;
    let zeroCount = lottos.filter(v => !v).length;

    const maxCount = minCount + zeroCount;

    return [rank[maxCount], rank[minCount]];
}
profile
영어강사, 프론트엔드 개발자를 거쳐 데이터 분석가를 준비하고 있습니다 ─ 데이터분석 블로그: https://cherylog.tistory.com/

0개의 댓글