프로그래머스 0단계, 이것만 알고 넘어가자!(1)

Daisy🌼·2023년 2월 8일
1

프로그래머스 0단계 문제를 풀면서 놓치기 쉬웠던 부분, 알아두면 좋은 부분을 기록합니다.🙂

프로그래머스 0단계에서 안 푼 문제 중, 정답률 높은 순으로 정렬하여 약 20문제를 풀어보았습니다. 물론 대부분의 문제를 10분 내에 풀이 방법을 도출해냈지만, 다른 사람의 풀이를 보면서 더 가독성있고 깔끔하게 작성할 수 있는 방법을 배우고 그 중에서 중요하다고 생각하는 부분에 대해서 공유하려고 합니다.

📝 옷가게 할인 받기

문제 링크

구간 별로 조건문을 작성할 때, 가장 큰 범위부터 작성해 리턴해주면 && 연산자를 사용해서 표현식을 2개를 써주지 않아도 되어 간결합니다. (구간을 나누는 조건문을 오랜만에 사용해봐서 잊고있었네요...)

function solution(price) {
    if (price >= 500000)
        return Math.floor(price*0.8);

    if (price >= 300000)
        return Math.floor(price*0.9);

    if (price >= 100000)
        return Math.floor(price*0.95);  

    return price
}

📝 배열의 유사도

문제 링크

array.filter()를 적절히 사용하면 코드가 간결해집니다.

📌 리팩토링 전

function solution(s1, s2) {
    const s1Obj = {};
    let count = 0;
    
    for(let el of s1) {
        s1Obj[el] = 0;
    }
    
  	// el이 객체의 key라면 count를 증가시킨다.
    for(let el of s2) {
        if(el in s1Obj) count++;
    }
    return count;
}

📌 리팩토링 후

function solution(s1, s2) {
	// filter로 s1 배열의 요소 el이 s2 배열에도 포함되어있는 경우만 filter된다.
    const numberOfTheSame  = s1.filter(el => s2.includes(el));
    
    return numberOfTheSame.length;
}

📝 제곱수 판별하기

문제 링크

Number.isInteger(숫자)는 주어진 숫자가 정수형인지 판별하는 메서드입니다. 그동안 사용해 본 적은 없었지만 나중에 유용하게 사용할 것 같습니다. Number.isInteger() - MDN

function solution(n) {
    return Number.isInteger(Math.sqrt(n)) ? 1 : 2;
}

📝 숨어있는 숫자의 덧셈(1)

문제 링크

replace() 메서드를 사용해 정규식을 만족하는 문자열을 제거할 수 있습니다 (빈 문자열 활용).

📌 리팩토링 전

function solution(my_string) {
  	// filter로 숫자인 요소만 리턴한다.
    const number = my_string.split('').filter(el => Number(el));
    
  	// 숫자를 더해 합을 구한다.
    return number.reduce((acc, cur) => acc + Number(cur), 0);
}

📌 리팩토링 후

function solution(my_string) {
    const answer = my_string.replace(/[^0-9]/g, '')
                            .split('')
                            .reduce((acc, curr) => acc + Number(curr), 0);
    return answer;
}

이 중에서 정규식 활용 부분만 따로 떼어서 보겠습니다.

const answer = my_string.replace(/[^0-9]/g, '')

replace 메서드는 첫 번째 인자로 정규식을, 두 번째 인자로 정규식을 만족하는 문자열을 대체할 문자열을 받습니다. 여기서 정규식은 /[^0-9]/g인데요. 이는 숫자가 아닌 모든 문자를 의미합니다. (/[^\d]/와 같이 쓸 수도 있습니다.)

''은 빈 문자열로, 비어있는 값이기 때문에 빈 문자열로 대체하면 요소를 제거하는 효과가 있습니다. 따라서 answer는 결과적으로 숫자로 이루어진 문자열이 될 것입니다.

이를 활용할 수 있는 비슷한 문제로는 같은 레벨의 모음 제거 문제가 있습니다.

📝 배열 회전 시키기

문제 링크

배열의 특정 원소를 옮기는 작업을 할 때는 배열 삽입, 삭제 메서드를 사용할 수 있습니다. 또한 array.at() 메서드를 사용법을 다시 한 번 배웠습니다.

📌 리팩토링 전

array.at() 메서드는 인덱스가 음수인 경우를 처리하기 위해 알아본 메서드입니다. 파이썬과 달리 자바스크립트에서는 대괄호 표기법을 사용해 음수 인덱스로 값에 접근할 수 없는데요. array.at() 메서드를 사용하면 음수를 넣어 값에 접근할 수 있습니다. 저는 해당 메서드를 활용해 문제를 풀었습니다.
Array.prototype.at() - MDN
[JS] 📚 자바스크립트에서 [-1] 인덱스 사용하기

function solution(numbers, direction) {
    const answer = new Array(numbers.length).fill(0);
    
    for(let i = 0; i < numbers.length; i++) {
        if(direction === "right") {
            answer[i] = numbers.at(i - 1);
        }
        
        if(direction === "left") {
            answer[i] = numbers.at(i - numbers.length + 1);
        }
    }
    return answer;
}

📌 리팩토링 후

배열의 요소를 값의 변화 없이 위치를 변경하는 문제이기 때문에, push(), pop(), unshife(), shift()를 사용할 수 있는 문제였습니다. 특히 이들 메서드는 원본 배열을 바꾸므로 새로운 배열을 할당하지 않아도 된다는 장점이 있습니다.

function solution(numbers, direction) {
    if(direction === "right") numbers.unshift(numbers.pop());
    if(direction === "left") numbers.push(numbers.shift());
    
    return numbers;
}

📝 인덱스 바꾸기

문제 링크

값을 교환할 때는 배열 구조 분해 할당!!

📌 리팩토링 전

특정 값을 다른 값으로 대체해야하기 때문에 splice()메서드를 사용했습니다. 다만 두 개를 서로 바꿔야 하므로 두 번 사용했고, splice()는 원본 배열을 변경하기 때문에 변경 이전의 값을 사용할 수 없으므로 복사본을 생성해 복사본의 배열 요소를 변경했습니다.

function solution(my_string, num1, num2) {
    const arr = [...my_string];
    
    arr.splice(num1, 1, my_string[num2]);
    arr.splice(num2, 1, my_string[num1]);
    
    return arr.join('');
}

📌 리팩토링 후

배열 구조 분해 할당은 변수의 값을 서로 교환할 수 있다는 특징이 있습니다. 구조 분해 할당 - MDN

문제에서도 두 값을 서로 변경하라는 조건이 있기 때문에, 배열 구조 분해 할당을 활용하면 splice()를 두 번 사용하지 않고도 한 줄로 값을 교환할 수 있습니다.

function solution(my_string, num1, num2) {
    my_string = my_string.split('');
  
  	// 값을 서로 바꿀 수 있다.
    [my_string[num1], my_string[num2]] = [my_string[num2], my_string[num1]];
  
    return my_string.join('');
}

📝 외계 행성의 나이

문제 링크

유니코드를 활용하는 법을 확실하게 짚고 넘어가자!

프로그래머스 문제를 풀다보면 유니코드를 활용해야 하는 문제들이 간간이 있습니다. 빈도가 그렇게 높지는 않지만, (정리를 안 하고 넘어가기 찝찝하여) 정리를 해두면 확실하게 짚고 넘어갈 수 있을 것입니다.

📌 빈출 유니코드

영어 대문자 A-Z: 65 ~ 90
영어 소문자 a-z: 97~ 122

📌 유니코드 관련 메서드

문자열.charCodeAt(숫자 인덱스): 문자열의 인덱스에 해당하는 요소가 유니코드 몇 번인지 알려주는 메서드 String.prototype.charCodeAt() - MDN

const str = 'ABCabc';

console.log(str.charCodeAt(0)); // 65
console.log(str.charCodeAt(1)); // 66
console.log(str.charCodeAt(2)); // 67
console.log(str.charCodeAt(3)); // 97
console.log(str.charCodeAt(4)); // 98
console.log(str.charCodeAt(4)); // 99

String.fromCharCode(숫자): 숫자에 대응하는 유니코드 문자열을 반환하는 메서드 String.fromCharCode() - MDN

console.log(String.fromCharCode(65)); // 'A'
console.log(String.fromCharCode(66)); // 'B'
console.log(String.fromCharCode(67)); // 'C'
console.log(String.fromCharCode(97)); // 'a'
console.log(String.fromCharCode(98)); // 'b'
console.log(String.fromCharCode(99)); // 'c'

이를 활용할 수 있는 문제는 같은 단계의 대문자와 소문자, 1단계의 시저 암호 등이 있습니다.


비록 쉬운 0단계 문제이지만, 놓치기 쉬운 부분들을 다시 짚고 넘어갈 수 있었고 체계적으로 문제를 해결하는 연습을 할 수 있었습니다. 다음 문제부터는 점점 정답률이 낮아지기 때문에 다음에도 정리하는 시간을 가져보겠습니다.🙂

profile
커피와 재즈를 좋아하는 코린이 | 좋은 글 좋은 코드를 쓰고 싶습니다

1개의 댓글

comment-user-thumbnail
2023년 7월 16일

프로그래머스 0단계 문제는 어느 정도 수준이면 풀 수 있을까요?
대략적인 문법은 숙지했는데, 풀이가 쉽지 않네요.

답글 달기