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

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

1. [프로그래머스] 0 떼기

문제설명 : n_str의 가장 왼쪽에 처음으로 등장하는 0들을 뗀 문자열을 리턴하세요.

입/출력 :

console.log(solution("0010")); // "10"

Solution1

  • 문자열을 배열로 만든 후 각 요소를 순회하면서 요소의 값이 1~9가 아닌 요소의 인덱스를 찾아 start 변수에 할당한다.
  • 그 후 반복문에서 start부터 마지막 요소까지 돌며 빈 문자열에 합쳐 리턴한다.
function solution(n_str) {
    let start = Array.from(n_str) // '0010'
        .findIndex((a) => '123456789'.indexOf(a) > -1);

    let result = '';
    for (let i = start; i < n_str.length; i++) {
        result += n_str[i];
    }

    return result;
}

Solution2

  • 숫자로 바꾸면 정수 앞에 0은 무시되므로 문자 타입 -> 숫자 타입으로 바꾼 후 다시 -> 문자 타입으로 바꾸어 리턴한다.
function solution(n_str) {  
  return Number(n_str).toString();
}

2. [프로그래머스] 꼬리 문자열

문제설명 : 문자열 리스트 str_list와 제외하려는 문자열 ex가 주어질 때, str_list에서 ex를 포함한 문자열을 제외한 모든 문자열들을 순서대로 합친 문자열을 리턴하세요.

입/출력 :

console.log(solution(["abc", "def", "ghi"], "ef")); // "abcghi"

Solution1

function solution(str_list, ex) {
  let result = "";
  for (let el of str_list) {
    if (!el.includes(ex)) {
      result += el;
    }
  }
  return result;
}

Solution2 : filter 활용하기

function solution(str_list, ex) {
  let result = str_list.filter((el) => !el.includes(ex)).join("");

  return result;
}

3. [프로그래머스] 마지막 두 원소

문제설명 : 마지막 원소가 그전 원소보다 크면 마지막 원소에서 그전 원소를 뺀 값을 마지막 원소가 그전 원소보다 크지 않다면 마지막 원소를 두 배한 값을 추가한 배열을 리턴하세요.

입/출력 :

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

Solution1

  • 마지막 원소와 그 앞 원소를 각각 length -1, -2를 하여 값을 구한다.
  • 맨 마지막 요소가 크다면 뺀 값을, 아니라면 마진막 요소 * 2한 값을 push한다.
function solution(num_list) {
  let end = num_list[num_list.length - 1];
  let frontEnd = num_list[num_list.length - 2];

  if (end > frontEnd) {
    num_list.push(end - frontEnd);
  } else { 
    num_list.push(end * 2);
  }
  return num_list;
}

Solution2 : 컴포넌트 재활용성 높이기

  • 요소의 i번째 값을 가져오는 함수 head와 tail을 구현한다.
function head(arr, n) {
    if (n === undefined) {
        return arr[0];
    }

    const result = [];
    for (let i = 0; i < n; i++) {
        result.push(arr[i]);
    }

    return result;
}

function tail(arr, n) {
    const copy = Array.prototype.slice.call(arr); 
    return head(copy.reverse(), n);
}

function solution(num_list) {
    const [end, frontEnd] = tail(num_list, 2);

    if (end > frontEnd) {
        num_list.push(end - frontEnd);
    } else {
        num_list.push(end * 2);
    }
    return num_list;
}

4. [프로그래머스] 배열의 원소만큼 추가하기

문제설명 : arr의 앞에서부터 차례대로 원소를 보면서 원소가 a라면 빈 배열 X의 맨 뒤에 a를 a번 추가하는 일을 반복한 뒤의 배열 X를 리턴하세요.

입/출력 :

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

Solution1

  • 반복문을 돌면서 Add함수에 i번째 요소와 배열을 전달한다.
  • Add 함수는 전달받은 요소를 배열에 추가한다.
function Add(n, arr) {
  for(let i = 0; i < n; i++) {
      arr.push(n);
  }
};

function solution(arr) {
  let result = [];
  
  for (let i = 0; i < arr.length; i++) {
      Add(arr[i], result)
  }
  return result;
}

Solution2

  • for문을 돌면서 i 요소로 채운 i개의 배열을 만들어 각 배열을 합친 배열을 리턴한다.
function solution(arr) {
  let result = [];
  
  for (let i = 0; i < arr.length; i++) {
    result = result.concat(new Array(arr[i]).fill(arr[i]));
  }
  return result;
}

5. [프로그래머스] 이어 붙인 수

문제설명 :

입/출력 : num_list의 홀수만 순서대로 이어 붙인 수와 짝수만 순서대로 이어 붙인 수의 합을 리턴하세요.

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

Solution1

  • 각 변수 even, odd에 짝수값, 홀수값을 각각 모은 후 숫자 타입으로 바꾸어 합을 구해 리턴한다.
function solution(num_list) {
  let even = num_list.filter((el) => el % 2 === 0).join("");
  let odd = num_list.filter((el) => el % 2 === 1).join("");

  return Number(even) + Number(odd);
}

Solution2 : filter 직접 구현하기

function solution(num_list) {
  let even = "";
  let odd = "";

  for (let i = 0; i < num_list.length; i++) { 
    if (num_list[i] % 2 === 0) {  
      even += num_list[i];
    } else {
      odd += num_list[i];
    }
  }
  return Number(even) + Number(odd);
}

6. [프로그래머스] 접두사인지 확인하기

문제설명 : my_string과 is_prefix가 주어질 때, is_prefix가 my_string의 접두사라면 1을, 아니면 0을 리턴하세요.

입/출력 :

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

Solution1

function solution(my_string, is_prefix) {

  for (let i = 1; i < my_string.length; i++) {
    if (my_string(0, i) === is_prefix) {
      return 1;
    }
  }
  return 0;
}

Solution2

function solution(my_string, is_prefix) {
    let prefix = "";

    for (let i = 0; i < is_prefix.length; i++) {
        prefix += my_string[i];
        if (prefix === is_prefix) {
            return 1;
        }
    }
    return 0;
}

7. [프로그래머스] 길이에 따른 연산

문제설명 : 리스트의 길이가 11 이상이면 리스트에 있는 모든 원소의 합을 10 이하이면 모든 원소의 곱을 리턴하세요.

입/출력 :

console.log(solution([3, 4, 5, 2, 5, 4, 6, 7, 3, 7, 2, 2, 1])); // 51

Solution1

function solution(num_list) {
  let add = 0;
  let multiple = 1;
  
  for (let i of num_list) {
      add += i;
      multiple *= i;
  }
  
  if (num_list.length >= 11) {
    return add;
  } else {
    return multiple;
  }
};

Solution2 : 함수 분리하여 유지보수성 높이기

  • 더하는 함수 add와 곱하는 함수 multiple을 구현한다.
  • f에 함수 add 또는 multiple을 할당한 후, 인자로 numbers을 전달한다.
function add(numbers) {
  let result = 0;
  for (let i of numbers) {
    result += i;
  }
  return result;
};

function multiple(numbers) {
  let result = 1;
  for (let i of numbers) {
    result *= i;
  }
  return result;
};

function solution(numbers, n) {
  const f = (numbers.length >= 11) ? add : multiple;
  return f(numbers);
};

8. [프로그래머스] 수 조작하기

문제설명 : 규칙에 따라 n을 바꿨을 때 가장 마지막에 나오는 n의 값을 리턴하세요.

입/출력 :

console.log(solution(0,	"wsdawsdassw")) // -1

Solution1

  • n부터 시작하여 control의 각 값을 키로 갖을 때, value의 함수를 실행한 값을 result에 누적으로 담아 리턴한다.
function solution(n, control) {
  let result = n;
  let arr = {
    "w": 1,
    "s": -1,
    "d": 10,
    "a": -10
  };

  for (let i = 0; i < control.length; i++) {
    result += arr[control[i]];
  }
  return result;
}

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

문제설명 : k가 홀수라면 arr의 모든 원소에 k를 곱하고, k가 짝수라면 arr의 모든 원소에 k를 더한 배열을 리턴하세요.

입/출력 :

console.log(solution([1, 2, 3, 100, 99, 98],	3)); // [3, 6, 9, 300, 297, 294]

Solution1

  • 삼항 연산자 사용하기
function solution(arr, k) {
  return (k % 2 == 1) ? arr.map((el) => (el * k)) : arr.map((el) => (el + k))
}

Solution2 : 함수 분리하기 & bind 함수 활용

  • 하는 일 분리 (함수 분리) : function add, function multi
  • bind 활용 및 커링
function add(a, b) {
    return a + b;
}

function multi(a, b) {
    return a * b;
}

const bindMulti = multi.bind(null, 20, 10);

function arrDo(arr, f) {
    return arr.map((el) => f(el));
}

// 커링
function solution(arr, k) {
    const f = (k % 2 === 1) ? multi.bind(null, k) : add.bind(null, k);
    return arrDo(arr, f);
}

10. [프로그래머스] 첫 번째로 나오는 음수

문제설명 : 첫 번째로 나오는 음수의 인덱스를 리턴하세요.

입/출력 :

console.log(solution([12, 4, 15, 46, 38, -2, 15])); // 5 

Solution1

function solution(num_list) {
  return num_list.findIndex(e => e < 0);
}

Solution2 : findIndex 구현하기

function solution(num_list) {
    for (let i = 0; i < num_list.length; i++) {
        if (num_list[i] < 0) {
            return i;
        }
    }

    return -1;
}
profile
한입 크기로 베어먹는 개발지식 🍰

2개의 댓글

comment-user-thumbnail
2023년 7월 24일

유익한 글이었습니다.

1개의 답글