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
의 마지막 값으로 넣었다.
5
와 0
만 있는 숫자를 찾기 위해 정규식을 사용했다. 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
을 하면 원하는 숫자의 인덱스까지 자를 수 있었다.
start
가 0
인 경우를 생각하지 못해 헤맸다. 인덱스에 0
을 아무리 더해도 end
는 배열에 들어가지 않는다. 조건을 더해 start
가 0
이면 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)];
}
종결점이 확실한 반복 계산이기에 재귀 함수
로 구현했다. n
이 1
이 될 때까지 조건에 맞춰 계산한 값을 인자로 넣는다. 마지막 값은 1
밖에 없으므로 [1]
을 넣는다. 배열로 감싼 이유는 재귀 함수
를 스프레드
용법으로 요소를 계속 추가하기 때문이다.
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
의 길이까지 반복하면 된다고 생각해 계속 틀렸다. 조건은 i
가 arr.length
보다 작으면이었다. pop()
일 경우 i
가 늘어나지 않으니 arr.length
보다 더 많이 반복문을 돌 수 있다. 따라서 while
문을 사용했다.
slice(음수)
를 하면 배열의 마지막부터 |음수|
만큼의 개수를 가진 배열을 반환한다. 매번 arr.length-1
로 마지막을 찾았는데, 이것보다 가독성이 훨씬 좋다.
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, 5
는 5
가 가장 많아 p
가 되어야 하지만, Set
은 앞에서부터 중복을 압축하여 1, 5
가 된다. 구조분해하면 p = 1
, rest = [5]
가 되기 때문에 두 번째 조건(rest.length === 1
)을 충족하기 어렵다. 10 * 1 + 5
와 10 * 5 + 1
은 전혀 다른 값이기 때문.
가장 많이 나온 순서로 정렬되도록 sort
콜백에 filter
를 추가했다. numArr
의 요소 중 a
, b
와 같은 요소만 필터링하여 길이로 빈도를 구했다. 가령 [1, 5, 5, 5]
에서 a = 1
의 필터 길이는 1
, b = 5
의 길이는 3
이고, 큰 숫자에서 작은 숫자를 빼므로 내림차순
정렬이 된다. [p, ...rest]
는 각각 [5, [1]]
이 되어 빈도까지 고려한 계산이 가능하다.