프로그래머스 Lv0 - 배열 만들기 2, 카운트 업, 콜라츠 수열 만들기, 배열 만들기 4, 주사위 게임 3

찐새·2023년 4월 27일
0

코딩테스트

목록 보기
34/53
post-thumbnail

배열 만들기 2

https://school.programmers.co.kr/learn/courses/30/lessons/181921

코드

function solution(l, r) {
    const answer = Array(r).fill(0).map((_,i)=>i+l);
    const arr = answer.slice(0, answer.indexOf(r)+1).filter((v)=>(v+"").match(/^5*(5|0)*$/g));
    return arr.length ? arr.sort((a,b)=>a-b) : [-1];
}

풀이

indexOf 사용하려고 변수를 두 개 작성했다.

생성한 배열의 마지막이 r로 끝난다고 착각하여 slice 두 번째 인자로 r을 넣었다. 당연히 실패. r까지만 배열이 남도록 원 배열에서 r의 인덱스를 찾아 +1하여 slice의 마지막 값으로 넣었다.

50만 있는 숫자를 찾기 위해 정규식을 사용했다. 5로 시작하며 여러 개이고, 가운데에는 5 또는 0이 여러 개 있으면서 그것으로 끝난다는 의미이다. 그러나 0으로 시작하는 일은 없으니 ^5*는 없어도 되었다. ^[05]+$으로 대체 가능.

카운트 업

https://school.programmers.co.kr/learn/courses/30/lessons/181920

코드

function solution(start, end) {
    return Array(start ? end : end + 1).fill(0).map((_, i)=>i+start).slice(0, end-start+1);
}

풀이

indexOf를 사용하지 않아도 end - start + 1을 하면 원하는 숫자의 인덱스까지 자를 수 있었다.

start0인 경우를 생각하지 못해 헤맸다. 인덱스에 0을 아무리 더해도 end는 배열에 들어가지 않는다. 조건을 더해 start0이면 end + 1로 배열을 생성하도록 했다.

콜라츠 수열 만들기

https://school.programmers.co.kr/learn/courses/30/lessons/181919

코드

function solution(n) {
    if (n === 1) return [1];
    const x = n % 2 ? (3 * n + 1) : n / 2
    return [n, ...solution(x)];
}

풀이

종결점이 확실한 반복 계산이기에 재귀 함수로 구현했다. n1이 될 때까지 조건에 맞춰 계산한 값을 인자로 넣는다. 마지막 값은 1밖에 없으므로 [1]을 넣는다. 배열로 감싼 이유는 재귀 함수스프레드 용법으로 요소를 계속 추가하기 때문이다.

배열 만들기 4

https://school.programmers.co.kr/learn/courses/30/lessons/181918

코드

function solution(arr) {
    const stk = [];
    let i = 0;
    while (i < arr.length) {
        if (!stk.length) {
            stk.push(arr[i]);
            i++;
        } else if (stk.slice(-1)[0] < arr[i]) {
            stk.push(arr[i]);
            i++;
        } else if (stk.slice(-1)[0] >= arr[i]) {
            stk.pop();
        }
    }
    return stk;
}

풀이

arr의 길이까지 반복하면 된다고 생각해 계속 틀렸다. 조건은 iarr.length보다 작으면이었다. pop()일 경우 i가 늘어나지 않으니 arr.length보다 더 많이 반복문을 돌 수 있다. 따라서 while문을 사용했다.

slice(음수)를 하면 배열의 마지막부터 |음수|만큼의 개수를 가진 배열을 반환한다. 매번 arr.length-1로 마지막을 찾았는데, 이것보다 가독성이 훨씬 좋다.

주사위 게임 3

https://school.programmers.co.kr/learn/courses/30/lessons/181916

코드

function solution(a, b, c, d) {
    const numArr = [a, b, c, d];
    const [p, ...rest] = [...new Set(numArr.sort((a,b)=>numArr.filter(v=>v===b).length - numArr.filter(v=>v===a).length))];
    if (!rest.length) return 1111 * p;
    if (rest.length === 1) {
        if (numArr.filter(v=>v===p).length === 2) return (p + rest[0]) * Math.abs(p - rest[0]);
        return (10 * p + rest[0]) ** 2;
    };
    if (rest.length === 2) return rest.reduce((a,c)=>a*c,1);
    return Math.min(a, b, c, d);
}

풀이

간단하게 중복처리만 하면 되는 문제라고 생각했지만, 한 가지 조건을 빼먹었다. Set에는 순서가 없으므로 빈도수가 높다고 앞으로 오지 않는다. 예를 들어, 1, 5, 5, 55가 가장 많아 p가 되어야 하지만, Set은 앞에서부터 중복을 압축하여 1, 5가 된다. 구조분해하면 p = 1, rest = [5]가 되기 때문에 두 번째 조건(rest.length === 1)을 충족하기 어렵다. 10 * 1 + 510 * 5 + 1은 전혀 다른 값이기 때문.

가장 많이 나온 순서로 정렬되도록 sort 콜백에 filter를 추가했다. numArr의 요소 중 a, b와 같은 요소만 필터링하여 길이로 빈도를 구했다. 가령 [1, 5, 5, 5]에서 a = 1의 필터 길이는 1, b = 5의 길이는 3이고, 큰 숫자에서 작은 숫자를 빼므로 내림차순 정렬이 된다. [p, ...rest]는 각각 [5, [1]]이 되어 빈도까지 고려한 계산이 가능하다.

profile
프론트엔드 개발자가 되고 싶다

0개의 댓글