"나는 무엇을 풀었는가" 시리즈는 이렇게 시작했습니다.
- 취업 준비 중 몇 번의 코딩테스트를 보며 깨달은 것이 있습니다. 바로 "기초가 중요하다"는 것입니다. 그리하여 프로그래머스 Level.0부터 차근차근 다시 풀어보려고 합니다.
- 단지 문제를 푸는 것보단, 왜 해당 함수를 썼는지 더 재사용이나 가독성을 높일 방법은 없는지, 그리고 해당 함수가 없다면 어떻게 풀 수 있을지와 같이 다양한 방법과 생각을 통해 사고력을 높이려고 노력합니다.
- 그럼 레츠 고 !
배열 내 각 요소들마다 중복 횟수를 구해 {요소 : 중복 횟수}
형태의 객체로 나타내고 싶다면 다음과 같은 방법을 사용할 수 있다.
예시 배열 :
const arr = ['A', 'B', 'C', 'D', 'A', 'A', 'C', 'E', 'D', 'E', 'A'];
1️⃣ forEach 활용하기
// {요소 : 중복 횟수} 형태로 전환한다.
const result = {};
arr.forEach((x) => {
result[x] = (result[x] || 0) + 1;
});
// {A: 4, B: 1, C: 2, D: 2, E: 2}
2️⃣ Reduce 활용하기
// result의 초기값으로 {}를 넣어준다.
const result = arr.reduce((result, x) => {
result[x] = (result[x] || 0) + 1;
return result;
}, {});
// {A: 4, B: 1, C: 2, D: 2, E: 2}
정렬을 위해 가장 많이 사용하는 메서드인 sort
는 객체에서눈 사용할 수 없다는 한계점이 있다. 그렇다면 객체의 key 또는 value를 기준으로 정렬하고 싶다면 어떻게 해야 할까?
예시 객체 :
{A: 4, B: 1, C: 2, D: 2, E: 2}
1️⃣ Object.value 활용하기
// 2. value 값을 기준으로 내림차순 정렬 후, 정렬된 key의 값을 가져온다.
return Object.values(result).sort((a, b) => a - b);
// [ 4, 2, 2, 2, 1 ]
2️⃣ Object.entries 활용하기
const arr = Object.entries(obj);
return arr.sort(([a1, b1], [a2, b2]) => b1 - b2);
// [ [ 'B', 1 ], [ 'C', 2 ], [ 'D', 2 ], [ 'E', 2 ], [ 'A', 4 ] ]
🎃 Object.entries
- 객체 → 배열 형태로 반환한다.
const obj = {A: 4}; return Object.entries(obj); // [ [ 'A', 4 ] ]
문제 3번 [프로그래머스] 세 개의 구분자
와 같이 인자 3개를 받는 함수가 있을 때, 인자 개수 전달에 따라 다른 리턴 값을 받고 싶다면?function splitWord(s, a, b) {
// 마지막 인자 b가 있는지 확인한다.
return b ? s.split(a).join(b) : s.split(a).filter(x => x);
}
// 인자 3개 모두 전달
const splitB = splitWord(splitA, 'b', 'c');
// 인자 2개만 전달
const splitC = splitWord(splitB, 'c');
문제설명 : 만약 date1이 date2보다 앞서는 날짜라면 1을, 아니면 0을 return 하는 solution 함수를 완성해 주세요.
입/출력 :
console.log(solution([2021, 12, 28] [2021, 12, 29])); // 1
function compare(a, b) {
return (a < b) ? 1 : 0;
}
function solution(date1, date2) {
const checkY = date1[0] === date2[0];
const checkM = date1[1] === date2[1];
const checkD = date1[2] === date2[2];
if (checkY && checkM && checkD) {
return 0;
} else if (checkY && checkM && !checkD) {
return compare(date1[2], date2[2])
} else if (checkY && !checkM && !checkD) {
return compare(date1[1], date2[1])
} else {
return compare(date1[0], date2[0])
}
}
function solution(date1, date2) {
return new Date(date1) < new Date(date2) ? 1 : 0;
}
function solution(date1, date2) {
return date1.join('') - date2.join('') < 0 ? 1 : 0;
}
문제설명 : 각 원소들을 길이가 같은 것끼리 그룹으로 묶었을 때, 최대가 되는 개수값을 리턴하세요.
입/출력 :
console.log(solution(["a", "bc", "d", "efg", "hi"])); // 2
function solution(strArr) {
// 1. 각 원소들을 원소의 길이로 값을 바꾸고 오름차순 정렬
const changeToLen = strArr.map(v => v.length);
// 2. 문자열 길이에 따른 갯수를 객체(키-벨류)형태로 만든다.
const result = {};
changeToLen.forEach((x) => {
result[x] = (result[x] || 0) + 1;
});
// 2번에서 만든 객체의 값만 가져와 내림차순으로 정렬한 후, 0번째 인덱스 값을 리턴한다.
return Object.values(result).sort((a, b) => b - a)[0];
}
function solution(strArr) {
// 1. 각 원소들을 원소의 길이로 값을 바꾸고 오름차순 정렬
const changeToLen = strArr.map(v => v.length);
// 2. 문자열 길이에 따른 갯수를 객체(키-벨류)형태로 만든다.
const xxxx = changeToLen.reduce((result, x) => {
result[x] = (result[x] || 0) + 1;
return result;
}, {});
// 2번에서 만든 객체의 값만 가져와 내림차순으로 정렬한 후, 0번째 인덱스 값을 리턴한다.
return Object.values(xxxx).sort((a, b) => b - a)[0];
}
문제설명 : 임의의 문자열이 주어졌을 때 문자 "a", "b", "c"를 구분자로 사용해 나눈 문자열을 배열에 담아 리턴하세요.
입/출력 :
console.log(solution("baconlettucetomato")); // ["onlettu", "etom", "to"]
function solution(myStr) {
const answer = myStr.split(/[a|b|c]/).filter((x) => x);
return answer.length > 0 ? answer : ["EMPTY"];
}
splitWord
함수를 구현한다.function splitWord(s, a, b) {
return b ? s.split(a).join(b) : s.split(a).filter(x => x);
}
function solution(s) {
const splitA = splitWord(s, 'a', 'b');
const splitB = splitWord(splitA, 'b', 'c');
const splitC = splitWord(splitB, 'c');
return splitC.length > 0 ? splitC : ["EMPTY"];
}
문제설명 : 조건 i + j <= k를 만족하는 board[i][j]의 합을 리턴하세요.
입/출력 :
console.log(solution([[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5]], 2)); // 8
function solution(board, k) {
let answer = 0;
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length ; j++) {
answer += i + j <= k ? board[i][j] : 0;
}
}
return answer;
}
문제설명 : start에서 end까지 1씩 감소하는 수들을 차례로 담은 리스트를 return하세요.
입/출력 :
console.log(solution(10, 3)); // [10, 9, 8, 7, 6, 5, 4, 3]
function solution(start, end) {
let result = [];
for (let i = end; i <= start; i++) {
result.unshift(i);
}
return result;
}
문제설명 : my_string의 모든 접미사를 사전순으로 정렬한 문자열 배열을 return 하는 solution 함수를 작성해 주세요.
입/출력 :
console.log(solution("banana"));
// ["a", "ana", "anana", "banana", "na", "nana"]
function solution(my_string) {
let arr = [];
for (let i = 0; i < my_string.length; i++) {
arr.push(my_string.slice(i));
}
return arr.sort();
}
문제설명 : is_suffix가 my_string의 접미사라면 1을, 아니면 0을 return 하는 solution 함수를 작성해 주세요.
입/출력 :
console.log(solution("banana", "ana")); // 1
function solution(my_string, is_suffix) {
return my_string.slice(my_string.length - is_suffix.length) === is_suffix
? 1 : 0;
}
문제설명 : 주사위를 세 번 굴려 나온 숫자를 각각 a, b, c라고 했을 때 조건에 맞는 점수를 리턴하세요.
조건 :
a + b + c
(a + b + c) × (a2 + b2 + c2)
(a + b + c) × (a2 + b2 + c2 ) × (a3 + b3 + c3 )
입/출력 :
console.log(solution(2, 6, 1)); // 9
function pow(a, b, c, n) {
return (Math.pow(a, n) + Math.pow(b, n) + Math.pow(c, n));
}
function solution(a, b, c) {
const x = pow(a, b, c, 1)
const y = x * pow(a, b, c, 2);
const z = x * pow(a, b, c, 2) * pow(a, b, c, 3);
return (a === b && b === c && c === a) ? z : (a !== b && b !== c && c !== a) ? x : y;
}
문제설명 : queries의 각 배열을 query라고 할때, arr[query]에 해당하는 값에 +1을 더한 배열을 리턴하세요.
입/출력 :
console.log(solution([0, 1, 2, 3, 4], [([0, 1], [1, 2], [2, 3])]));
// [1, 3, 4, 4, 4]
function solution(arr, queries) {
queries.map(([s, e]) => {
for (let i = s; i <= e; i++) {
arr[i] += 1;
}
})
return arr;
}
문제설명 : queries의 각 원소는 하나의 query를 나타내며 [i, j]꼴입니다. 이때 arr[i]의 값과 arr[j]의 값의 위치를 바꾸어 모든 query 배열이 반영된 arr를 리턴하세요.
입/출력 :
console.log(solution([0, 1, 2, 3, 4], [([0, 3], [1, 2], [1, 4])])); // [3, 4, 1, 0, 2]
function solution(arr, queries) {
queries.forEach(([i, j]) => {
[arr[i], arr[j]] = [arr[j], arr[i]];
});
return arr;
}