"나는 무엇을 풀었는가" 시리즈는 이렇게 시작했습니다.

  1. 취업 준비 중 몇 번의 코딩테스트를 보며 깨달은 것이 있습니다. 바로 "기초가 중요하다"는 것입니다. 그리하여 프로그래머스 Level.0부터 차근차근 다시 풀어보려고 합니다.
  2. 단지 문제를 푸는 것보단, 왜 해당 함수를 썼는지 더 재사용이나 가독성을 높일 방법은 없는지, 그리고 해당 함수가 없다면 어떻게 풀 수 있을지와 같이 다양한 방법과 생각을 통해 사고력을 높이려고 노력합니다.
  3. 그럼 레츠 고 !

1. [프로그래머스] 1로 만들기

문제설명 : num_list의 모든 원소를 1로 만들기 위해서 필요한 나누기 연산의 횟수를 리턴하세요.

조건 :
1. 짝수라면 n/2, 횟수++
2. 홀수라면 (n - 1)/2, 횟수++
3. 위 과정을 1이 될때까지 반복하여 각 원소를 1로 만들기 위해 필요한 총 횟수를 리턴하세요.

입/출력 :

console.log(solution([12, 4, 15, 1, 14])); // 11

Solution1 : 관심사 분리

  • num_list에 map을 돌려 calculator함수에 각 요소를 인자로 전달한다.
  • calculator 함수 : 초기값이 0인 변수를 선언하고, n이 1이 되기 전까지 짝수/홀수 조건을 반복하면서 횟수를 증가시킨다.
    → 각 요소가 1이 될때까지 연산된 횟수 : [ 3, 2, 3, 0, 3 ]
  • 연산된 횟수가 담긴 배열을 reduce를 통해 값을 누적하여 리턴한다.
function calculator(n) {
  let result = 0;

  while (n !== 1) {
    n = n % 2 === 0 ? n / 2 : (n - 1) / 2;
    result += 1;
  }

  return result;
}

function solution(num_list) {
  return num_list.map(calculator).reduce((a, b) => a + b, 0);
}

Solution2 : 재귀함수 구현

function calculator(n) {
    if (n === 1) {
        return 0;
    }

    return 1 + calculator(n % 2 === 0 ? n / 2 : (n - 1) / 2);
}

function solution(num_list) {
    return num_list.map(calculator).reduce((a, b) => a + b, 0);
}

2. [프로그래머스] 2의 영역

문제설명 : 배열 안의 2가 모두 포함된 가장 작은 연속된 부분 배열을 리턴하세요. 단, arr에 2가 없는 경우 [-1]을 리턴하세요.

입/출력 :


console.log(solution([1, 2, 1, 4, 5, 2, 9])); // [2, 1, 4, 5, 2]

Solution1

  • 2가 등장한 첫번째 인덱스와 마지막 인덱스를 찾아 slice하여 리턴한다.
function solution(arr) {
  let a = arr.indexOf(2);
  let b = arr.lastIndexOf(2) + 1;
  
  return a !== -1 ? arr.slice(a, b) : [-1];
}

3. [프로그래머스] 뒤에서 5등까지

문제설명 : num_list에서 가장 작은 5개의 수를 오름차순으로 담은 리스트를 리턴하세요.

입/출력 :

console.log(solution([12, 4, 15, 46, 38, 1, 14])); // [1, 4, 12, 14, 15]

Solution1

function solution(num_list) {
  return num_list.sort((a, b) => a - b).slice(0, 5);
}

4. [프로그래머스] 뒤에서 5등 위로

문제설명 : num_list에서 가장 작은 5개의 수를 제외한 수들을 오름차순으로 담은 리스트를 리턴하세요.

입/출력 :

console.log(solution([12, 4, 15, 46, 38, 1, 14])); // [1, 4, 12, 14, 15]

Solution1

function solution(num_list) {
  return num_list.sort((a, b) => a - b).slice(0, 5);
}

5. [프로그래머스] 문자 개수 세기

문제설명 : my_string에서 'A'의 개수, my_string에서 'B'의 개수,..., my_string에서 'Z'의 개수, my_string에서 'a'의 개수, my_string에서 'b'의 개수,..., my_string에서 'z'의 개수를 순서대로 담은 길이 52의 정수 배열을 리턴하세요.

입/출력 :

console.log(solution("Programmers")); 
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0]

Solution1 : 아스키 코드 활용하기

👉 직접 정리한 인덱스 - 아스키코드 관계표

  • 52개의 0으로 채운 배열 하나를 만든다.
  • my_string 배열을 돌면서 각각의 요소가 대문자라면 각 요소의 아스키코드 - 65번째 값에 1을 더하고, 소문자라면 - 71한 값에 1을 더해 리턴한다.
function solution(my_string) {
  let arr = Array(52).fill(0);

  [...my_string].map((alp) => { 
    const code = alp.charCodeAt(alp); // 아스키코드 확인
      // 대문자라면
      if (alp === alp.toUpperCase()) {
        return arr[code - 65] += 1;
      } else {
        return arr[code - 71] += 1;
      }
  })
  
  return arr;
}

Solution2 : 공통 작업 분리

  • counterUpper/counterLower 함수 : counterCommon 함수에 my_string과 대문자 또는 소문자 알파벳을 문자열로 전달한다.
  • counterCommon 함수 : 26개의 0으로 채운 배열 하나를 만들고, 각 index에 해당하는 값에 1씩 증가시킨다.
function counterCommon(s, alphabetCase) {
    const result = new Array(26).fill(0);

    for (let i = 0; i < s.length; i++) {
        const alp = s[i];
        const index = alphabetCase.indexOf(alp);
        if (index > -1) {
            result[index] += 1;
        }
    }
    return result;
}

function counterUpper(my_string) {
    return counterCommon(my_string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
}

function counterLower(my_string) {
    return counterCommon(my_string, 'abcdefghijklmnopqrstuvwxyz');
}

function solution(s) {
    return counterUpper(s).concat(counterLower(s));
}

6. [프로그래머스] 부분 문자열 이어 붙여 문자열 만들기

문제설명 : my_strings의 원소의 parts에 해당하는 부분 문자열을 순서대로 이어 붙인 문자열을 리턴하세요.
→ my_strings[i].slice(parts[i][0], parts[i][1] + 1)한 문자열을 순서대로 이어 붙인 문자열을 리턴하세요.

입/출력 :

console.log(solution(["progressive", "hamburger", "hammer", "ahocorasick"], [[0, 4], [1, 2], [3, 5], [7, 7]])); // "programmers"

Solution1 : map 함수 활용하기

function solution(my_strings, parts) {
  return my_strings.map((el, i) => el.slice(parts[i][0], parts[i][1] + 1)).join('');
}

Solution2 : map 직접 구현하기

function solution(my_strings, parts) {
  let result = "";
    
  for (let i = 0; i < my_strings.length; i++) {
    result += my_strings[i].slice(parts[i][0], parts[i][1] + 1);
  }
    
  return result;
}

7. [프로그래머스] 부분 문자열인지 확인하기

문제설명 : target이 문자열 my_string의 부분 문자열이라면 1을, 아니라면 0을 리턴하세요.

입/출력 :

console.log(solution("banana", "ana")); // 1

Solution1

function solution(my_string, target) {
  return my_string.includes(target) ? 1 : 0;
}

8. [프로그래머스] 조건에 맞게 수열 변환하기 1

문제설명 : arr의 각 원소에 대해 값이 50보다 크거나 같은 짝수라면 2로 나누고, 50보다 작은 홀수라면 2를 곱합니다. 그 결과인 정수 배열을 리턴하세요.

입/출력 :

console.log(solution([1, 2, 3, 100, 99, 98])); // [2, 2, 6, 50, 99, 49]

Solution1

function solution(arr) {
  return arr.map((el) => {
    if (el >= 50 && el % 2 === 0) return el / 2;
    else if (el < 50 && el % 2 === 1) return el * 2;
    else return el;
  })
}
profile
한입 크기로 베어먹는 개발지식 🍰

0개의 댓글