[JavaScript] 코딩 테스트 LV.0 풀기

coolriver·2023년 8월 2일

JavaScript

목록 보기
9/10
post-thumbnail

최댓값 만들기(1)

문제 설명:
정수 배열 numbers가 매개변수로 주어집니다. numbers의 원소 중 두 개를 곱해 만들 수 있는 최댓값을 return하도록 solution 함수를 완성해주세요.

풀이:

function solution(numbers) {
    let answer = numbers.sort((a, b) => a - b) 
    // numbers 배열을 순서대로 정렬하여 answer라는 배열에 할당
    return answer[numbers.length - 1] * answer[numbers.length -2];
  // 정렬한 배열 answer에서 맨 뒷 값과 그 전 값을 곱하면 최댓값
}


개미 군단

문제 설명
개미 군단이 사냥을 나가려고 합니다. 개미군단은 사냥감의 체력에 딱 맞는 병력을 데리고 나가려고 합니다. 장군개미는 5의 공격력을, 병정개미는 3의 공격력을 일개미는 1의 공격력을 가지고 있습니다. 예를 들어 체력 23의 여치를 사냥하려고 할 때, 일개미 23마리를 데리고 가도 되지만, 장군개미 네 마리와 병정개미 한 마리를 데리고 간다면 더 적은 병력으로 사냥할 수 있습니다. 사냥감의 체력 hp가 매개변수로 주어질 때, 사냥감의 체력에 딱 맞게 최소한의 병력을 구성하려면 몇 마리의 개미가 필요한지를 return하도록 solution 함수를 완성해주세요.

풀이:

function solution(hp) {
let 장군 = 5, 병정 = 3, 일개미 = 1;
let= 0;
let 나머지 = (hp % 장군);+= parseInt(hp / 장군);+= parseInt(나머지 / 병정);
나머지 = (나머지 % 병정)+= parseInt(나머지 / 일개미_;
return;
}

처음에 문제 보고 이해가 안 가서 하나씩 차근차근 풀어 봤다. 주어진 hp를 공격력이 큰 순서대로 나누고 그 값을 합산하여 반환하면 되는 거였다.

다른 풀이:

function solution(hp) {
    let sum = 0; // 합산할 값 0으로 할당
    let temp = hp; // 나머지의 초깃값을 hp로 할당
    for (let i = 5; i >= 1; i -= 2){ 
      // 장군개미 공격력인 5부터 -2씩 차례로 병정개미, 일개미 공격력을 반복
        sum += parseInt(temp / i); // hp에서 개미의 공격력으로 나누기
        temp = parseInt(temp % i); // 나머지에서 개미의 공격력으로 나눈 나머지를 다시 할당
    }
    return sum;

그래서 반복되는 부분들을 for문으로 만들었다. 처음엔 배열을 만들어서 for문을 썼다가 for문의 조건식을 바꿔 주면 되지 않을까 싶어 for문의 조건식을 5, 3, 1로 만들어 주었다. 로직을 접근하는 것도 어려웠지만 for문으로 변환하는 것도 쉽지 않았던 문제였다..



주사위의 개수

문제 설명
머쓱이는 직육면체 모양의 상자를 하나 가지고 있는데 이 상자에 정육면체 모양의 주사위를 최대한 많이 채우고 싶습니다. 상자의 가로, 세로, 높이가 저장되어있는 배열 box와 주사위 모서리의 길이 정수 n이 매개변수로 주어졌을 때, 상자에 들어갈 수 있는 주사위의 최대 개수를 return 하도록 solution 함수를 완성해주세요.

풀이:

function solution(box, n) {
    let sum = 1; // 주사위의 개수를 합산할 변수 sum 선언
    for(let x of box){ // for of문을 사용하여 배열 순회
        sum *= parseInt(x / n); // 순회하며 n을 배열의 원소의 값으로 나누어 sum에 합산
    }return sum;
}

예제를 보고 가로 길이, 세로 길이, 높이 길이 전부를 n으로 나눈 다음 합산하면 result 값이 나온다는 걸 깨닫게 되었다. 그래서 for of문을 사용하여 배열을 순회하고 sum에 합산하는 코드를 짰다. sum이 0인 경우 sum *= parseInt(x / n) 값이 모두 0이 되기 때문에 1로 주었다.



피자 나눠 먹기(2)

문제 설명:
머쓱이네 피자가게는 피자를 여섯 조각으로 잘라 줍니다. 피자를 나눠먹을 사람의 수 n이 매개변수로 주어질 때, n명이 주문한 피자를 남기지 않고 모두 같은 수의 피자 조각을 먹어야 한다면 최소 몇 판을 시켜야 하는지를 return 하도록 solution 함수를 완성해보세요.

풀이:

function solution(n) {
  for (let i = 1; ; i++) { // n이랑 곱할 임의의 수 i 선언
    if ((n * i) % 6 === 0) { // (n * i) 값이 6의 배수인 경우
      return (n * i) / 6; // (n * i)를 6으로 나눈 몫을 반환한다.
    }
  }
}

접근하는 게 좀 어려웠던 문제다.. 수학에 약해서 하나하나 적어가면서 했는데 예시를 계속 봤을 때, (n * 어떤 수)를 했을 때 가장 첫 번째로 나오는 6의 배수가 총 조각 수라고 생각했다. 그래서 그걸 다시 6으로 나눈 몫을 반환했다.

아 그리고 for 조건식 부분에서 i에 제한을 걸면 큰 수일 때 값이 안 나오는 것 같아서 제한을 풀고 공백으로 뒀다.
쓰면서도 사실 복잡한데 어떻게 풀어 내긴 했다.. 다른 분들 풀이 보니까 그냥 i % 6 하면 되더라. 나는 바보

순서쌍의 개수

문제 설명:
순서쌍이란 두 개의 숫자를 순서를 정하여 짝지어 나타낸 쌍으로 (a, b)로 표기합니다. 자연수 n이 매개변수로 주어질 때 두 숫자의 곱이 n인 자연수 순서쌍의 개수를 return하도록 solution 함수를 완성해주세요.

풀이

function solution(n) {
    let sum = 0; // 순서쌍의 개수를 할당할 변수 sum 초기화
    for(let i = 1; i <= n; i++){ // 0은 무엇을 곱하든 0이기 때문에 1부터 시작
        if(n % i === 0){ // 자연수 n이 i로 나누어지면 순서쌍에 포함된다.
            sum++ // 순서쌍의 개수 증가
        }
    }return sum;
}

처음엔 이중 for문에 if문 조건식으로 두 값을 곱한 값이 20이면 sum++가 되는 코드를 썼었는데 시간 초과로 정답 처리가 안 됐다. 생각해 보니까 n의 값이 10000인 경우엔 너무나도 비효율적인 코드였다. 그래서 for문 하나로 처리할 수 있는 방법은 없을까? 해서 코드를 새로 짰다.

어떻게 할까 생각해 본 결과, n을 i로 나누었을 때 0이 된다는 건 결국 어떤 값과 어떤 값이 곱해진 개수가 아닐까 싶었다. 제대로 파악한 건지는 모르겠지만, 어차피 한 값만 구해도 다른 한 값은 무조건 존재할 수 밖에 없으니까 한 값의 개수만 구해도 되는 문제였다.

이런 수학적인 문제를 내가 풀어냈다는 게 너무 뿌듯하다....



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

문제 설명:
문자열 my_string이 매개변수로 주어집니다. my_string안의 모든 자연수들의 합을 return하도록 solution 함수를 완성해주세요.

풀이

function solution(my_string) {
  return my_string.split('') // 문자열을 원소 하나하나로 쪼갠 배열로 만들기
                  .map(x => parseInt(x)) // 문자열 -> 숫자로 변환
                  .filter(x => !isNaN(x)) // !isNaN으로 NaN이 아닌 숫자 걸러내기
                  .reduce((a,b) => a+b); // 더한 값 누적하기
}

우선 배열의 메서드들을 배운 상태라 문제에 응용해 보고 싶었다. 그래서 for문을 쓰기보다 메서드를 이용해서 풀어 봤다. split('')을 했을 때 자꾸 '' 이게 붙어서 나와서 이걸 어떻게 처리할지에 대해 많이 고민했다.
고민 끝에 숫자열로 변환을 했는데 이젠 또 NaN 때문에 난리.. typeof도 써 봤지만 NaN 또한 Number로 처리 돼서 애를 많이 먹었다... 겨우 isNaN을 통해 숫자를 걸러내고 reduce도 처음 써 봤는데 성공!!



인덱스 바꾸기

문제 설명:
문자열 my_string과 정수 num1, num2가 매개변수로 주어질 때, my_string에서 인덱스 num1과 인덱스 num2에 해당하는 문자를 바꾼 문자열을 return 하도록 solution 함수를 완성해보세요.

풀이

function solution(my_string, num1, num2) { 
    let arr = []; // 새 배열 생성
    let n1 = my_string[num1], n2 = my_string[num2]; // num1 값, num2 값을 저장함
    for(let i = 0; i < my_string.length; i++){ 
        arr.push(my_string[i]) // arr 배열에 문자 하나씩 추가
        }
    arr[num1] = n2; // arr num1 값에 저장해 둔 n2 값을 넣음
    arr[num2] = n1; // arr num2 값에 저장해 둔 n1 값을 넣음
    return arr.join(''); // arr를 다시 문자열로
    }

이 문제에서는 for문에 다른 동작을 넣을 게 아니라면 split()을 썼으면 됐는데 for문을 넣어서 좀 길어진 것 같다. arr[num1] = n2arr[num2] = n1 부분을 한꺼번에 바꾸고 싶었는데 어떻게 하는지를 몰라서 이것저것 해 봤는데 잘 안 돼서 결국 따로 하게 되었다.

다른 분들의 풀이를 보니까 [arr[num1], arr[num2]] = [arr[num2], arr[num1]] 이렇게 가능하더라.. 난 계속 [arr[num1, num2] 이런 식으로 시도 했는데.. 그래도 새로운 걸 알게 되었다!

풀이 수정

function solution(my_string, num1, num2) { 
    let str = my_string.split('')
    let n1 = my_string[num1], n2 = my_string[num2];
    str[num1] = n2; 
    str[num2] = n1; 
    return str.join('');
    }

for문을 split()으로 대체해 보기.



피자 나눠 먹기 (3)

문제 설명:
머쓱이네 피자가게는 피자를 두 조각에서 열 조각까지 원하는 조각 수로 잘라줍니다. 피자 조각 수 slice와 피자를 먹는 사람의 수 n이 매개변수로 주어질 때, n명의 사람이 최소 한 조각 이상 피자를 먹으려면 최소 몇 판의 피자를 시켜야 하는지를 return 하도록 solution 함수를 완성해보세요.

풀이

function solution(slice, n) {
    return n % slice === 0 ? n / slice : parseInt(n / slice) + 1;
} // 먹는 사람에서 조각 수로 나누고 나머지가 0이라면 몫 만큼,
// 0이 아닌 경우엔 몫 + 1만큼을 주문하면 된다.


중복된 문자 제거

문제 설명:
문자열 my_string이 매개변수로 주어집니다. my_string에서 중복된 문자를 제거하고 하나의 문자만 남긴 문자열을 return하도록 solution 함수를 완성해주세요.

풀이

function solution(my_string) {
    let str = my_string.split('') // 문자열을 하나씩 쪼개기
    let answer = ''; // 새로운 문자열 생성
    for (let i = 0; i < str.length; i++){ // 쪼갠 문자열을 for문으로 순회
        if(!answer.includes(str[i])){ // answer에 같은 문자가 없는 경우
            answer += str[i]; // answer에 str[i] 값을 넣는다
        }
    } return answer; // 값 반환
}


약수 구하기

문제 설명
정수 n이 매개변수로 주어질 때, n의 약수를 오름차순으로 담은 배열을 return하도록 solution 함수를 완성해주세요.

풀이

function solution(n) { 
    let set = new Set(); // 중복된 값을 제거하기 위해 Set 생성
    for(let i = 1; i <= n; i++){ // 약수 값을 찾기 위해 for문 순회
            if(n % i  == 0){ // 약수 값을 판별하는 if문
                set.add(n / i); //만약 약수라면, 약수 값을 Set에 추가
            }
    }return [...set].sort((a, b) => a - b); // 오름차순 정렬 후 반환
}

이 문제는 사실 set이 따로 필요한 건 아니었는데, 내가 약수를 떠올리면서 전에 봤던 문제인 합성수 찾기랑 비슷하게 찾으면 되지 않을까? 싶어서 처음엔 이중 for문을 썼었다. 그러면서 console.log를 찍어 봤는데 중복 값이 너무 많이 나와서 중복된 값을 지우기 위해 set을 쓰게 됐었는데 결론적으로는 내부 for문도, set도 굳이 필요하지 않았던 문제..

풀이 수정

function solution(n) { 
    let arr = []; // set 대신 배열 생성
    for(let i = 1; i <= n; i++){ // 똑같이 약수 구하는 for문
            if(n % i  == 0){ // 약수인지 판별 후
                arr.push(i); // 약수라면 arr 배열에 추가
            }
    }return(arr);
}

이렇게 쉽게 풀 수 있던 문젠데 너무 어렵게 간 것 같다. 약수 관련 문제가 나오면 무조건 나누기를 생각하자!!



369게임

문제 설명:
머쓱이는 친구들과 369게임을 하고 있습니다. 369게임은 1부터 숫자를 하나씩 대며 3, 6, 9가 들어가는 숫자는 숫자 대신 3, 6, 9의 개수만큼 박수를 치는 게임입니다. 머쓱이가 말해야하는 숫자 order가 매개변수로 주어질 때, 머쓱이가 쳐야할 박수 횟수를 return 하도록 solution 함수를 완성해보세요.

풀이

function solution(order) {
    let arr = String(order).split(''); // order을 문자열로 변환 후 하나씩 쪼개기
    let count = 0; // 박수를 몇 번 치는지 체크하는 count
    for(let index of arr){ 
        for(let i = 3; i <= 9; i += 3){ 
          // arr를 돌면서 3, 6, 9를 대입해 보는 이중 for문 작성
        if(index.includes(i) === true){ // index에 3, 6, 9가 포함이라면
            count++; // 박수 카운트를 센다
            break; // 카운트를 센 경우 다음 외부 for문으로 가기
        }
    }
    }return count;
}

처음엔 3, 6, 9를 order의 수 하나하나랑 비교해야 된다고 생각해서 이중 for문을 작성했다. 근데 이중 for문은 효율이 떨어진단 이야기를 들어서 풀이를 다시 바꿔 보고 싶었다.

다른 풀이

function solution(order) {
    let arr = String(order).split('');
    let count = 0;
    for(let index of arr){
       index === '3' || index === '6' || index === '9' ? count++ : null;
      // index의 값이 3, 6, 9인 경우 박수 카운트를 세고 아닌 경우 null
        }return count;
}

조건을 이런 식으로 주면 이중 for문이 아닌 삼항연산자(또는 if문)로도 가능하다.

다른 풀이

function solution(order) {
   return String(order).split('') // 문자열로 변환, 쪼개기
        .map(x => Number(x)) // 다시 숫자로 변환 후 배열로 반환
        .filter((x) => [3, 6, 9].includes(x)).length; // 3, 6, 9인 원소들의 수를 반환
}

다시 또 메서드를 활용하여 풀어 봤다. 하나의 문제를 다양하게 풀 수 있다는 게 재밌다.



숫자 찾기

문제 설명:
정수 num과 k가 매개변수로 주어질 때, num을 이루는 숫자 중에 k가 있으면 num의 그 숫자가 있는 자리 수를 return하고 없으면 -1을 return 하도록 solution 함수를 완성해보세요.

풀이

function solution(num, k) {
    let arr = String(num).split('').map(x => Number(x));
  // num을 문자열로 변환 후 쪼개고 다시 숫자 배열로 반환
  
    return arr.indexOf(k) === -1 ? arr.indexOf(k) : arr.indexOf(k) +1;
  // indexOf를 활용하여 k가 들어가는 index를 찾고 자리 수를 반환해야 하기 때문에
  // indexOf 값이 -1이 아닌 경우 +1을 반환
}

이 문제는 사실 보자마자 indexOf가 떠올랐다. 자리 수를 반환해야 되기 때문에 따로 그 부분만 +1 처리를 했다.



한 번만 등장한 문자

문제 설명:
문자열 s가 매개변수로 주어집니다. s에서 한 번만 등장하는 문자를 사전 순으로 정렬한 문자열을 return 하도록 solution 함수를 완성해보세요. 한 번만 등장하는 문자가 없을 경우 빈 문자열을 return 합니다.

풀이

function solution(s) {
    let arr = [];
    for(let x of s){ // for of문으로 s를 순회
        // x의 인덱스 값이 첫 번째와 마지막이 같다면 arr에 push
        s.indexOf(x) === s.lastIndexOf(x) ? arr.push(x) : null;
    }
    return arr.sort().join('') // 정렬 후 반환
}

중복이라는 소릴 보고 처음엔 set도 써 봤다가 for문도 썼다가 while문도 썼다가 이것저것 다 해 봤는데 잘 안 됐다. indexOf를 써야 될 것 같긴 한데 어떤 식으로 써야 될지 도통 감이 안 와서 다른 분 풀이를 참고해서 푼 문제.. indexOflasIndexOf를 같이 쓴다는 생각을 하는 게 되게 기발한 것 같다.



7의 개수

문제 설명:
머쓱이는 행운의 숫자 7을 가장 좋아합니다. 정수 배열 array가 매개변수로 주어질 때, 7이 총 몇 개 있는지 return 하도록 solution 함수를 완성해보세요.

풀이

function solution(array) {
   let count = 0;
   for (i of array){
       let str = i.toString()
       for(y=0; y<str.length; y++){
           if(str[y] === "7"){
               count++
           }
       } 
   }   
    return count;
}  

// array의 배열 요소를 문자열로 변환
// 문자열로 변환 뒤 각 index에 있는 문자가 7인지 확인
// 7인 경우 count에 넣기

너무 오랜만에 푼 문제여서 천천히 하나씩 로직을 짜 보고 for of문과 for문을 사용하여 결론적으로는 이중 for문을 써서 풀었다. 주석에 나온대로 문자열로 변환 후 각 index에 7이 몇 개 포함되는지 세는 구조로 풀어냈다.

다른 사람 풀이

function solution(array) {
    return array.join('').split('7').length-1;
}

근데 이걸 보고 놀랐다.. 이렇게 간단하게 joinsplit을 써서 풀어낼 수 있구나 싶었고 메서드 사용이 오랜만이기도 해서 기억을 못 했던 것 같다.



컨트롤 제트

문제 설명:
숫자와 "Z"가 공백으로 구분되어 담긴 문자열이 주어집니다. 문자열에 있는 숫자를 차례대로 더하려고 합니다. 이 때 "Z"가 나오면 바로 전에 더했던 숫자를 뺀다는 뜻입니다. 숫자와 "Z"로 이루어진 문자열 s가 주어질 때, 머쓱이가 구한 값을 return 하도록 solution 함수를 완성해보세요.

풀이

function solution(s) {
    let sum = 0;
    s.split(" ").forEach((x, i) => {
        x !== "Z" ?
        sum += Number(x) :
        sum -= s.split(" ")[i-1]
    })
    return sum;
}
// 문자열 s를 나눠서 배열화 시키기
// 반복문으로 합을 더하기
// 문자열 Z인 경우 전 순서에 더한 값을 빼기

하나씩 차근차근 문자열을 배열화 시키고 forEach를 통해 요소 값을 숫자로 변경 후 합산했다. 문자열 Z인 경우엔 forEachindex를 이용하여 전 값을 빼는 방식으로 풀어냈다.


다른 사람 풀이

// 1
function solution(s) {
    const stack = []

    s.split(' ').forEach((target) => {
        if(target === 'Z') stack.pop();
        else stack.push(+target)
    })

    return stack.length ? stack.reduce((pre, cur) => pre + cur) : 0;
}

// 2
function solution(s) {

    let arr = s.split(" ");

    while ( arr.indexOf('Z') > -1) {

        arr.splice( arr.indexOf('Z')-1, 2);
    }

    return arr.reduce((a,b) => parseInt(a) + parseInt(b),0)
}

1번과 같이 stack 형태로 pop 메서드를 쓰는 것과 2번과 같이 indexOf를 쓰면 보다 직관적으로 풀어낼 수 있었을 것 같다.

profile
코생아

0개의 댓글