"나는 무엇을 풀었는가" 시리즈는 이렇게 시작했습니다.
- 취업 준비 중 몇 번의 코딩테스트를 보며 깨달은 것이 있습니다. 바로 "기초가 중요하다"는 것입니다. 그리하여 프로그래머스 Level.0부터 차근차근 다시 풀어보려고 합니다.
- 단지 문제를 푸는 것보단, 왜 해당 함수를 썼는지 더 재사용이나 가독성을 높일 방법은 없는지, 그리고 해당 함수가 없다면 어떻게 풀 수 있을지와 같이 다양한 방법과 생각을 통해 사고력을 높이려고 노력합니다.
- 그럼 레츠 고 !
Number
vs BigInt
두 수의 합
문제를 풀다보니 Number
로는 통과되지 않았던 문제가 BigInt
로 바꾸니 통과되는걸 알게 되었다. 무슨 차이일까 ?
Number 데이터 타입
Number.MAX_SAFE_INTEGER의 값
, 즉 9007199254740991(2^53 - 1)
으로, 이보다 큰 값은 제대로 연산되지 않을 수 있다.BigInt 데이터 타입
Number.MAX_SAFE_INTEGER의 값
을 초과한 큰 정수도 안전하게 저장하고 조작 할 수 있다.문제설명 : 0 이상의 두 정수가 문자열 a, b로 주어질 때, a + b의 값을 문자열로 return 하는 solution 함수를 작성해 주세요.
입/출력 :
console.log(solution("582", "734")); // "1316"
function solution(a, b) {
const answer = BigInt(a) + BigInt(b);
return answer.toString();
}
BigInt
를 사용해 문제를 해결할 수 있다.BigInt
: Number 원시 값이 안정적으로 나타낼 수 있는 최대치인 2^53 - 1보다 큰 정수를 표현할 수 있는 내장 객체이다.입/출력 :
console.log(solution([1, 4, 2, 5, 3])); // [1, 2, 3]
풀이 노트 :
1. 변수 i를 초기값 0으로 설정하고, i < arr.length일 때 아래 작업을 반복한다.
2. stk.length === 0 ? stk.push(arr[i]) i++;
3. stk.length > 0 && stk[stk.length - 1] < arr[i] ? stk.push(arr[i]) i++;
4. stk.length > 0 && stk[stk.length - 1] >= arr[i] ? stk.pop();
function solution(arr) {
let stk = [];
let i = 0;
while(i < arr.length) {
if (stk.length === 0) {
stk.push(arr[i]);
i++;
} else {
if (stk[stk.length - 1] < arr[i]) {
stk.push(arr[i]);
i++;
} else {
stk.pop();
}
}
}
return stk;
}
문제설명 : 각 학생들의 선발 고사 등수를 담은 정수 배열 rank와 전국 대회 참여 가능 여부가 담긴 boolean 배열 attendance가 매개변수로 주어집니다. 전국 대회에 선발된 학생 번호들을 등수가 높은 순서대로 각각 a, b, c번이라고 할 때 10000 × a + 100 × b + c를 return 하는 solution 함수를 작성해 주세요.
입/출력 :
console.log(solution([3, 7, 2, 5, 4, 6, 1], [false, true, true, true, true, false, false])); // 20403
function answer(a, b, c) {
return a * 10000 + b * 100 + c;
}
function solution(rank, attendance) {
const arr = rank.map((el, idx) => [el, idx]).filter((_, idx) => attendance[idx]).sort((a, b) => a[0] - b[0]);
return answer(arr[0][1], arr[1][1], arr[2][1]);
}
문제설명 : ineq는 "<"와 ">"중 하나고, eq는 "="와 "!"중 하나입니다. 그리고 두 정수 n과 m이 주어질 때, n과 m이 ineq와 eq의 조건에 맞으면 1을 아니면 0을 return하도록 solution 함수를 완성해주세요.
입/출력 :
console.log(solution("<", "=", 20, 50)); // 1
eq === "="
이라면 withEqual
함수에, 아니라면 withoutEqual
함수에 파라미터로 전달하여 답을 리턴한다.function withEqual(ineq, n, m) {
if (ineq === "<") {
return n <= m ? 1 : 0;
} else {
return n >= m ? 1 : 0;
}
}
function withoutEqual(ineq, n, m) {
if (ineq === "<") {
return n < m ? 1 : 0;
} else {
return n > m ? 1 : 0;
}
}
function solution(ineq, eq, n, m) {
return (eq === "=") ? withEqual(ineq, n, m) : withoutEqual(ineq, n, m);
}
ineq + eq
를 객체의 키값으로, n, m
은 value의 파라미터로 전달해 답을 얻는다.
const ops = {
'>=': (n, m) => (n >= m) ? 1 : 0,
'<=': (n, m) => (n <= m) ? 1 : 0,
'>!': (n, m) => (n > m) ? 1 : 0,
'<!': (n, m) => (n < m) ? 1 : 0,
}
function solution(ineq, eq, n, m) {
return ops[ineq + eq](n, m);
}
문제설명 : 두 정수 q, r과 문자열 code가 주어질 때, code의 각 인덱스를 q로 나누었을 때 나머지가 r인 위치의 문자를 앞에서부터 순서대로 이어 붙인 문자열을 return 하는 solution 함수를 작성해 주세요.
입/출력 :
console.log(solution(3, 1, "qjnwezgrpirldywt")); // "jerry"
function solution(q, r, code) {
return [...code].filter((el, i) => i % q == r ? el : "").join("");
}
문제설명 : num_list를 조건 n에 따라 자른 배열을 리턴하세요.
조건 :
1. slicer에 담긴 정수는 차례대로 a, b, c이다.
2. n의 조건은 다음과 같다.
입/출력 :
console.log(solution(3, [1, 5, 2], [1, 2, 3, 4, 5, 6, 7, 8, 9])); // [2, 3, 4, 5, 6]
function solution(n, slicer, num_list) {
const [a, b, c] = slicer;
if(n === 1) {
return num_list.slice(0, b+1);
}
if(n === 2) {
return num_list.slice(a, num_list.length+1);
}
if(n === 3) {
return num_list.slice(a, b+1);
}
if(n === 4) {
let arr = [];
for (let i = a; i <= b; i+= c) {
arr.push(num_list[i])
}
return arr;
}
}
const sliceList = {
1: (arr, [a, b, c]) => arr.slice(0, b + 1),
2: (arr, [a, b, c]) => arr.slice(a),
3: (arr, [a, b, c]) => arr.slice(a, b + 1),
4: (arr, [a, b, c]) => arr.slice(a, b + 1).filter((_, idx) => idx % c === 0)
}
function solution(n, slicer, num_list) {
return sliceList[n](num_list, slicer);
}
문제설명 : my_string에서 인덱스 s부터 인덱스 e까지를 뒤집은 문자열을 return 하는 solution 함수를 작성해 주세요.
입/출력 :
console.log(solution("Progra21Sremm3", 6, 12)); // "ProgrammerS123"
join()
을 통해 문자열로 리턴한다.function solution(my_string, s, e) {
const a = my_string.slice(0, s);
const b = [...my_string.slice(s, e+1)].reverse();
const c = my_string.slice(e+1, my_string.length);
return [...a, ...b, ...c].join("")
}
문제설명 : 문자열 myString에서 pat이 등장하는 횟수를 리턴하세요.
입/출력 :
console.log(solution("banana", "ana")) // 2
myString.slice(i, i + pat.length)
과 pat
이 같다면 cnt++한다.function solution(myString, pat) {
let cnt = 0;
for (let i = 0; i < myString.length; i++) {
if (myString.slice(i, i + pat.length) === pat) {
cnt++;
}
}
return cnt;
}
문제설명 : flag[i]가 true라면 배열 X에 arr[i] * 2번 arr[i]
요소를 추가하고, 아니라면 배열 X에 arr[i]
개의 요소를 맨 뒤에서부터 제거하여 최종적으로 배열 X를 리턴하세요.
입/출력 :
console.log(solution([3, 2, 4, 1, 3], [true, false, true, false, false]));
// [3, 3, 3, 3, 4, 4, 4, 4]
function addElement(arr, el) {
for (let i = 0; i < el * 2; i++) {
arr.push(el);
}
}
function deleteElement(arr, el) {
for (let i = 0; i < el; i++) {
arr.pop();
}
}
function solution(arr, flag) {
let X = [];
arr.map((v, i) => flag[i] === true ? addElement(X, v) : deleteElement(X, v));
return X;
}
문제설명 : n 번째 원소부터 마지막 원소까지의 모든 원소를 담은 리스트를 return하세요.
입/출력 :
console.log(solution([5, 2, 1, 7, 5], 2)); // [2, 1, 7, 5]
function solution(num_list, n) {
return num_list.slice(n-1);
}