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

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

1. [프로그래머스] 9로 나눈 나머지

문제설명 : 문자열 number로 주어질 때, 이 정수를 9로 나눈 나머지를 리턴하세요.

입/출력 :

console.log(solution("123")); // 6

Solution1

  • reduce를 통해 초기값 0에 각 요소를 누적으로 더해주고, 합계를 9로 나눠주어 리턴한다.
function solution(number) {
  let answer = [...number].reduce((a, b) => a + Number(b), 0);

  return answer % 9;
}

2. [프로그래머스] 가까운 1찾기

문제설명 : idx보다 크면서 배열의 값이 1인 가장 작은 인덱스를 찾아 리턴하세요.

입/출력 :

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

Solution1

function solution(arr, idx) {
  let result = -1;
  
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === 1 && i >= idx) {
      return i;
    }
  }
  return -1;
}

3. [프로그래머스] 콜라츠 수열 만들기

문제설명 : x가 짝수일 때는 2로 나누고, x가 홀수일 때는 3 * x + 1로 바꾸는 계산을 반복해 이 과정에서 거쳐간 모든 수를 기록한 수열을 리턴하세요.

입/출력 :

console.log(solution(10)); // [10, 5, 16, 8, 4, 2, 1]

Solution1

function solution(n) {
  let result = [n];
  
  while(n !== 1) {
    if (n % 2 === 0) {
      n = n / 2;
      result.push(n);
    } else {
      n = 3 * n + 1;
      result.push(n);
    }
  }
  return result;
}

4. [프로그래머스] 문자열 잘라서 정렬하기

문제설명 : "x"를 기준으로 해당 문자열을 잘라내 배열을 만든 후 사전순으로 정렬한 배열을 리턴하세요.

입/출력 :

console.log(solution("axbxcxdx")); // ["a","b","c","d"]

Solution1

function solution(myString) {
  return myString.split("x")
    .filter((el) => el !== "")
    .sort();
  
}

5. [프로그래머스] 세로 읽기

문제설명 : my_string을 한 줄에 m 글자씩 가로로 적었을 때 왼쪽부터 세로로 c번째 열에 적힌 글자들로 만든 문자열을 리턴하세요.

입/출력 :

console.log(solution("ihrhbakrfpndopljhygc", 4, 2)); // 4	2	"happy"

Solution1

  • 반복문을 통해 m씩 요소를 잘라 빈 배열에 넣어준다.
  • 그 후 map을 사용해 c번째 요소를 새로운 빈 문자열에 담아 리턴한다.
function solution(my_string, m, c) { 
  let result = []; // ["ihrh","bakr","fpnd","oplj","hygc"]
  let answer = "";
  
  for (let i = 0; i < my_string.length ; i += m) {
    let row = my_string.slice(i, i + m)
    result.push(row);
  }
  result.map((el) => answer += el[c - 1]);
  return answer;
}

Solution2 : 단계 줄이기

  • 반복문을 돌면서 [i + c - 1]번째 요소를 빈 문자열에 담아 리턴한다.
function solution(my_string, m, c) { 
  let answer = "";
  
  for (let i = 0; i < my_string.length ; i += m) {
    answer += my_string[i + c - 1]; // (0 + 2 - 1) = 1 --> (4 + 2 - 1) = 5 ...
  }
  return answer;
}

6. [프로그래머스] 특정 문자열로 끝나는 가장 긴 부분 문자열 찾기

문제설명 : pat로 끝나는 가장 긴 부분 문자열을 찾아 리턴하세요.

입/출력 :

console.log(solution("AbCdEFG", "dE")); // "AbCdE"

Solution1

  • lastIndexOf를 통해 마지막 pat의 인덱스를 구한다.
  • 'dE' 처럼 길이가 1이상일 수 있기 때문에 (n + pat.length)까지 구한다.
function solution(myString, pat) {
  const n = myString.lastIndexOf(pat);
  return myString.slice(0, n + pat.length);
}

Solution2 : lastIndexOf 직접 구현하기

function solution(myString, pat) {
  let last = 0;
  for (let i = 0; i < myString.length; i++) {
    // 첫 요소가 같다면
    if (myString[i] === pat[0]) {
      if (myString.slice(i, i + pat.length) === pat) {
        last = i + pat.length;
      }
    }
  }
  return myString.slice(0, last);
}

7. [프로그래머스] 홀짝에 따라 다른 값 반환하기

문제설명 : n이 홀수라면 n 이하의 홀수인 모든 양의 정수의 합을 리턴하고 n이 짝수라면 n 이하의 짝수인 모든 양의 정수의 제곱의 합을 리턴하세요.

입/출력 :

console.log(solution(7)); // 16

Solution1

function add(a, b) {
  return a + b;
}

function filter(n, start) {
  const result = [];

  for (let i = start; i < n; i += 2) {
    result.push(i);
  }

  return result;
}

function solution(n) {
  let result = 0;

  if (n % 2 === 0) {
    result = filter(n + 1, 0).map(x => x * x).reduce(add);
  } else {
    result = filter(n + 1, 1).reduce(add);
  }

  return result;
}

Solution2 : 관심사 분리

function calculator(n, answer, f) {
  for (let i = n; i > 0; i -= 2) {
    answer += f(i);
  }
  return answer;
}

function solution(n) {
  let answer = 0;
  return n % 2 === 0
      ? calculator(n, answer, x => x * x)
      : calculator(n, answer, x => x);
}

8. [프로그래머스] rny_string

문제설명 : ny_string의 모든 'm'을 "rn"으로 바꾼 문자열을 리턴하세요.

입/출력 :

console.log(solution("masterpiece")); // "rnasterpiece"

Solution1

function solution(rny_string) {
  return rny_string.replaceAll('m', 'rn');
}

Solution2 : replaceAll 직접 구현하기

function solution(rny_string) {
  let arr = rny_string.split("");
  let str = '';
  
  for(let i = 0; i < arr.length; i++) {
       str += (arr[i] === 'm') ? 'rn' : arr[i];
  }
  return str;
}

9. [프로그래머스] 배열 비교하기

문제설명 : 두 정수 배열의 대소관계의 결과를 리턴하세요.

[비교 조건] :
1. 길이가 다르다면 → 배열의 길이가 긴쪽이 더 크다
2. 길이가 같다면 → 배열의 각 원소의 합이 큰 쪽이 크고 또는 같다.

[출력 조건] :
1. arr1 < arr2 라면 -1
2. arr1 > arr2 라면 1
3. arr1 = arr2 라면 0

입/출력 :

console.log(solution([49, 13], [70, 11, 2])); // -1

Solution1

function solution(arr1, arr2) {
  let result = 0;
  
  //1. 길이가 다를때
  if (arr1.length !== arr2.length) {
    result = (arr1.length < arr2.length) ? -1 : 1;
  } else { 
    //2. 길이가 같을 때
    const a = arr1.reduce((acc, cur) => (acc + cur), 0);
    const b = arr2.reduce((acc, cur) => (acc + cur), 0);
      
    result = (a < b) ? -1 : (a > b) ? 1 : 0;
  }

  return result;
}

Solution2 : 관심사 분리하기

  • 대소 비교를 하는 함수 : compare
  • 누적으로 합계를 구하는 함수 : add
  • 결과를 리턴하는 함수 : solution
function compare(a, b) {
  if(a === b) {
    return 0;
  } else {
    return (a > b ? 1 : -1); 
  }
}

function add(arr) {
  return arr.reduce((acc, cur) => (acc + cur), 0);
}

function solution(arr1, arr2) {
  let result = 0;
  
  //1. 길이가 다를때
  if (arr1.length !== arr2.length) {
    result = compare(arr1.length, arr2.length);
  } else { 
    //2. 길이가 같을 때   
    result = compare(add(arr1), add(arr2));
  }

  return result;
}

10. [프로그래머스] 배열의 원소 삭제하기

문제설명 : arr의 원소 중 delete_list의 원소를 모두 삭제하고 남은 원소들을 기존의 arr에 있던 순서대로 나열해 리턴하세요.

입/출력 :

console.log(solution([293, 1000, 395, 678, 94], [94, 777, 104, 1000, 1, 12])); // [293, 395, 678]

Solution1 : filter & includes

function solution(arr, delete_list) {
    return arr.filter(el => !delete_list.includes(el));
}

Solution2 : includes 직접 구현하기

  • delete_list의 원소와 일치하는 arr[i]번 요소를 delete한다.
  • filter를 통해 null 값이 아닌 값만 리턴한다.
function solution(arr, delete_list) {

  for (let i = 0; i < arr.length ; i++) {
    for (let j = 0; j < delete_list.length ; j++) {
      if (arr[i] === delete_list[j]) {
        delete arr[i];
      }
    }
  }
  return arr.filter(el => el !== null);
}

Solution3 : true/false 여부를 반환하는 변수 flag 사용하기

function solution(arr, dList) {
    const result = [];

    for (let i = 0; i < arr.length; i++) {
        let flag = false;

        for (let j = 0; j < dList.length; j++) {
            if (dList[j] === arr[i]) {
                flag = true;
                break;
            }
        }

        if (!flag) {
            result.push(arr[i]);
        }
    }

    return result;
}

Solution4 : filter & includes 직접 구현하고 관심사 분리하기

function includes(arr, x) {
    let flag = false;

    for (let i = 0; i < arr.length; i++) {
        if (arr[i] === x) {
            flag = true;
            break;
        }
    }

    return flag;
}

function filter(arr, f) {
    const result = [];

    for (let i = 0; i < arr.length; i++) {
        if (f(arr[i])) {
            result.push(arr[i]);
        }
    }

    return result;
}

function solution(arr, dList) {
    return filter(arr, (x) => !includes(dList, x));
}
profile
한입 크기로 베어먹는 개발지식 🍰

0개의 댓글