본문 바로가기
JavaScript/Coding test

프로그래머스 코딩테스트 Lv.1 풀이 1

by enai 2024. 1. 11.

2023.12.11

짝수와 홀수

function solution(num) {
    const answer =  num % 2 === 0 ? 'Even' : 'Odd'
    return answer;
}

나머지를 구하는 % 연산자를 이용해 짝수, 홀수 구분함

문자열을 정수로 바꾸기

function solution(s) {
    return Number(s);
}

Number 생성자를 이용해 문자열을 숫자로 바꿈

평균 구하기

function solution(arr) {
    const total = arr.reduce((acc, curr) => acc + curr, 0)
    const answer = total / arr.length
    return answer;
}

reducearr의 요소들을 모두 더한 후, arr의 개수만큼 나눔 다른 코드를 보고 reduce 끝의 initialValue를 생략 가능하다는 걸 새로 배웠음 (생략하면 initialValue가 첫번째 요소가 되고, curr에 오는 처리할 현재 요소가 두번째 요소부터 시작됨)

2023.12.12

약수의 합

function solution(n) {
    let answer = 0;
    for (let i = 1; i <=n; i++) {
        if (n % i === 0) {
            answer = answer + i
        }
    }
    return answer;
}

반복문으로 나머지가 없는 값들을 찾아서 더해주기

나머지가 1이 되는 수 찾기

function solution(n) {
     var answer = 0;
    
    for (let i = 0; i < n; i++) {
        if (n % i === 1) {
            answer = i;
            break;
        }
    }
   
    return answer;
}

반복문으로 i를 1씩 증가해 나머지가 1이 되는 순간 answer에 저장하고 반목문 멈추기

x만큼 간격이 있는 n개의 숫자

function solution(x, n) {
    const answer = Array.from({length: n}).map((_v, i) => x * (i + 1))
    return answer;
}

Array.from으로 n 길이의 빈 객체를 만들기 x * 1, x * 2, ... 값 만들어 배열에 담기
Array.from보다 Array.fill이 좀 더 빠름! 테스트 케이스가 큰 건 아니라 미묘한 차이지만, 앞으로 배열을 만들 때 fill을 쓰는 게 좋을 거 같음

2023.12.13

문자열 내 P와 Y의 개수

function solution(s){
    let p = 0;
    let y = 0;
    s.split('').forEach((c) => {
        switch(c.toLowerCase()) {
            case 'p':
                p++;
                break;
            case 'y':
                y++;
                break;
        }
    })

    const answer = p === y
    return answer;
}

s를 한글자씩 나눠 배열로 만든 후 각 글자를 모두 소문자로 만들어 'p'p 변수에 +1, 'y'y 변수에 +1 하여 두 변수 값이 같은지 비교함 +) 처음엔 if문으로 비교했는데, forEachcontinue를 사용할 수 없어 switch문으로 바꿨습니다.

자릿수 더하기

function solution(n)
{
    const answer = n.toString().split('').reduce((acc, curr) => acc + parseInt(curr), 0)
    return answer;
}

숫자인 n을 문자열로 바꾼 후 한 글자씩 나눠 배열로 만듦 reduce로 각 요소들을 숫자로 다시 바꿔주고 모두 더함

자연수 뒤집어 배열로 만들기

function solution(n) {
    const answer = [...n.toString()].map((item) => parseInt(item)).reverse()
    return answer;
}

숫자 n을 문자열로 변환한 후 spread 연산자로 한 글자씩 나뉜 배열 생성 각 요소들을 다시 숫자로 변환하고, reverse로 배열을 뒤집음

2023.12.14

정수 제곱근 판별

function solution(n) {
    const x = Math.sqrt(n)
    if (Number.isInteger(x)) {
        return Math.pow(x+1, 2)
    }
    return -1;
}

Math.sqrt로 제곱근을 구하고, 제곱근 x가 정수면 x^2 = n이 됨 -> Number.isIntegerx가 정수인지 확인 정수라면 Math.powx+1의 제곱을 리턴하고 아니면 -1을 리턴

정수 내림차순으로 배치하기

function solution(n) {
    const numArr = n.toString().split('')
    const answer = Number(numArr.sort((a, b) => b - a).join(''))
    return answer;
}

n을 각 자릿수를 나눠 배열로 만듦 배열을 내림차순으로 정렬한 후 다시 합친 후, 숫자로 형변환 하여 리턴

하샤드 수

function solution(x) {
    let num = x
    let sum = 0
    while(num > 0) {
        sum += num % 10
        num = Math.floor(num / 10)
    }
    const answer = x % sum === 0
    return answer;
}

xnum에 저장
1. num을 10으로 나눈 나머지 수 === 1의 자리 숫자 -> sum에 더하기
2. numnum을 10으로 나눈 몫으로 바꿔 저장
num이 0보다 같거나 작아질 때까지 1, 2를 반복 => sum === x 각 자릿수의 합 x 를 sum으로 나누어 떨어지면 true, 아니면 false를 반환함

p.s. 이전 풀이에서 각 자릿수를 모두 더할 때 문자 배열을 만들지 않고, 계속 10으로 나눠 1의 자리 숫자만 가져와서 더하는 방식을 봤었는데, 이 방법이 효율적인 거 같아 이번에 사용해 봄 그때 봤던 건 do while 이었는데, 풀이 당시엔 while문만 생각나서 while을 사용함. x는 1 이상이기 때문에 처음엔 무조건 실행 조건에 맞기 때문에 do while을 쓰는 것이 좋아보임

2023.12.15

두 정수 사이의 합

function solution(a, b) {
    const [min, max] = [a, b].sort((prev, curr) => prev - curr)
    
    // if (min === max) {
    //     return a
    // } // a와 b가 같은 경우 둘 중 아무 수를 리턴하는 로직을 넣었는데, 없어도 상관 없었음
    
    let answer = min
    for (let i = min+1; i <= max; i++) {
        answer += i;
    }
    return answer;
}
a, b를 오름차순으로 정렬한 후, 작은 수부터 시작해 큰 수가 될 때까지 1씩 늘려 더함
[추가내용]
  1. a,b를 오름차순으로 정렬할 때 비교함수 없이 [a, b].sort() 이렇게 했었음 -> 순서 정렬 의도대로 x, 유니 코드 순서대로 정렬됨 (1, 1000, 20 이렇게 정렬될 수 있다는 뜻!) 새롭게 알았음
  2. 등차수열의 합 공식으로 더 간단하게 풀 수 있음

콜라츠 추측

function solution(num) {
    let answer = 0;
    let curr = num;
    while (curr > 1) {
        if (curr % 2 === 0) {
            curr /= 2;
        } else {
            curr = curr * 3 + 1;
        }
        answer++;

        if (answer === 500) return -1;
    }
        
    return answer;
}

주어진 수가 1일 때는 0을 반환해야 하므로 answer은 0부터 시작 콜라츠 추측 규칙을 실행할 조건은 num이 1 초과일 때로 설정해서 while로 반복해서 answer에 반복횟수 누적한 후 반환 answer가 500일 땐 -1 반환

음양 더하기

function solution(absolutes, signs) {
    let answer = 0;
    absolutes.forEach((abs, index) => {
        // 처음 풀이
        // signs[index] ? answer += abs : answer -= abs;
        answer += signs[index] ? abs : -abs;
    })
    return answer;
}

absolutes의 각 숫자 위치와 signs의 위치가 같으므로 absolutes의 index를 이용해 해당하는 부호 가져옴. 부호가 true면 해당 숫자를 anser에 더해주고, false면 빼줌

2023.12.16

서울에서 김서방 찾기

function solution(seoul) {
    const index = seoul.findIndex((name) => name === 'Kim')
    var answer = `김서방은 ${index}에 있다`;
    return answer;
}

findIndex'Kim'이 있는 index를 찾고, 문장 만들어서 반환함

나누어 떨어지는 숫자 배열

function solution(arr, divisor) {
    const divisible = arr.filter((el) => el % divisor === 0)
    const answer = divisible.length > 0 ? divisible.sort((a, b) => a - b) : [-1];
    return answer;
}

divisor로 나누어 떨어지는 수를 filter로 찾아서 divisible에 저장
divisible의 길이가 0보다 크면 내림차순으로 정렬해서 반환, 아니면 [-1] 반환

없는 숫자 더하기

function solution(numbers) {
    const sumOfAll = (0+9)*10/2;
    const sumOfNumbers = numbers.reduce((acc, curr) => acc + curr);
    const answer = sumOfAll - sumOfNumbers;
    return answer;
}

등차수열의 합 공식으로 0~9까지의 합을 구하고, reducenumbers의 합을 구함
총합에서 numbers의 합을 빼서 구한 없는 숫자의 합을 반환

2023.12.17

핸드폰 번호 가리기

function solution(phone_number) {
    const answer = '*'.repeat(phone_number.length - 4) + phone_number.slice(-4);
    return answer;
}

repeat을 이용해 '^'을 phone_number - 4 만큼 만든 후, slice로 phone_number의 마지막 4자리를 붙여서 반환

[추가내용]
다른 사람 코드를 보니 정규 표현식으로도 할 수 있음. 정규표현식을 알고는 있지만 전혀 생각지 못했음. 다음에 정규표현식이 가능할 때 한번 떠올려 보도록 하겠음
repeat은 padStart로 대체 가능

제일 작은 수 제거하기

function solution(arr) {
    let min = arr[0]
    for (let i = 1; i < arr.length; i++) {
        if (min > arr[i]) {
            min = arr[i]
        }
    }
    const answer = arr.filter((el) => el !== min)
    
    return answer.length > 0 ? answer : [-1]
}

for문으로 arr을 돌면서 각 요소들의 크기를 비교해 min 변수에 가장 작은 수 담기
arr에서 min이랑 같지 않은 요소의 배열만 answer에 저장
answer의 길이가 0보다 크면 빈 배열이 아니므로 answer
, 아니면 빈 배열이므로 [-1]을 반환

[추가내용]
Math.min, indexOf, splice로 간단하게 해결 가능. 다 아는 문법이지만, 당시 떠올리지 못함

가운데 글자 가져오기

function solution(s) {
    const length = s.length
    // if (length === 1) return s
    
    const index = Math.ceil(length / 2) - 1
    if (length % 2 === 0) {
        return s[index]+s[index + 1]
    }
    return s[index]
}

글자의 가운데 index는 길이를 2로 나눠 올림한 후 1을 빼서 구함
글자수가 짝수면 가운데 index의 글자와 그 옆의 글자를 반환
글자수가 홀수면 가운데 index의 글자를 반환

[추가내용]
substring은 떠올리지 못해서 아쉬움

2023.12.18

내적

function solution(a, b) {
    let answer = 0;
    for (let i = 0; i < a.length; i++) {
        answer += a[i] * b[i]
    }
    return answer;
}

각 배열의 같은 인덱스 값을 곱해 answer에 계속 더해서 반환

수박수박수박수박수박수?

function solution(n) {
    const answer = new Array(n).fill().map((_v, i) => {
        if (i % 2 === 0) return '수';
        return '박';
    }).join('')
    return answer;
}

빈 배열을 만들고 인덱스가 짝수면 '수', 홀수면 '박'인 배열로 만든 후 문자열로 만들어 반환

[추가내용]
repeat을 사용하면 더 간단하게 만들 수 있음

약수의 개수와 덧셈

function solution(left, right) {
    let answer = 0;
    for (let n = left; n <= right; n++){
        const divisor = new Array(n).fill().filter((_v, i) => n % (i + 1) === 0);
        if (divisor.length % 2 === 0) {
            answer += n;
        } else {
            answer -= n;
        }
    }
    return answer;
}

left부터 right까지 약수를 구해 약수의 수가 짝수인지 홀수인지 확인 후 수를 더하거나 뺌
총합을 리턴

2023.12.19

문자열 내림차순으로 배치하기

function solution(s) {
    const answer = [...s].sort().reverse().join('');
    return answer;
}

부족한 금액 계산하기

function solution(price, money, count) {
    const totalPrice = (2 * price + (count - 1) * price) * count / 2;
    const answer = totalPrice > money ? totalPrice - money : 0;
    return answer;
}

문자열 다루기 기본

function solution(s) {
    const length = s.length;
    return /^[0-9]+$/.test(s) && (length === 4 || length === 6);
}

2023.12.20

행렬의 덧셈

function solution(arr1, arr2) {
    const answer = []
    const arrLength = arr1.length
    const elementsLength = arr1[0].length
    
    for (let i = 0; i < arrLength; i++) {
        const arr = []
        for (let j = 0; j < elementsLength; j++) {
            arr.push(arr1[i][j] + arr2[i][j])
        }
        answer.push(arr)
    }
    return answer;
}

2023.12.21

같은 숫자는 싫어

function solution(arr)
{
    const answer = arr.filter((el, i) => el !== arr[i-1])
    
    return answer;
}

이전 요소와 같지 않는 요소만 filter하기

3진법 뒤집기

function solution(n) {
    const answer = parseInt(n.toString(3).split('').reverse().join(''), 3)
    return answer;
}

toString(3)으로 3진수로 바꾼 다음, 배열로 만들어 뒤집어 다시 문자열로 바꿈
parseInt로 다시 10진수로 바꿔서 반환

예산

function solution(d, budget) {
    const departments = d.sort((a,b) => a-b)
    let answer = departments.length
    const test = departments.reduce((acc, curr, i) => {
        const sumOfPrice = acc + curr
        if (sumOfPrice > budget) {
            departments.splice(i)
            answer = i
            return acc
        }
        return sumOfPrice
    }, 0)
    return answer;
}

최대한 많은 부서를 지원하기 위해 적은 필요한 금액이 적은 순부터 지원
-> 부서별 필요한 금액 배열을 오름차순으로 정렬
각 금액들을 누적해서 더하고 budget과 비교해 예산이 넘으면 해당 금액 다시 제거
, 이때 index가 지원한 부서 개수이므로 해당 index를 반환

 

댓글