코딩테스트 연습(Lv0 / 034 ~ 037)- Day09 수학, 문자열, 해시, 완전탐색, 조건문

Kang.__.Mingu·2023년 1월 7일
0

코딩테스트(Lv0)

목록 보기
10/26

개미 군단

개미 군단

문제

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


function solution(hp) {
  	// x는 장군, y는 병정, z는 일개미
    let x = 5, y = 3, z = 1;
    
  	// 싸웠을 때 몫
    let xf, yf, zf;

    if(hp % x !== 0){
      	// 싸웠을 때 몫이 얼마인지
        xf = Math.floor(hp / x);
      	// 싸우고 난 나머지
        hp = hp % x;
        if(hp % y !==0){
            yf = Math.floor(hp / y);
            hp = hp % y;
          	// z는 1이기 때문에 무조건 나눠져야 됨
            if(hp % z == 0){
                zf = Math.floor(hp / z);
                return xf + yf + zf;
            }
        } else {
            yf = Math.floor(hp / y);
            return xf + yf;
        }
    } else {
        xf = hp / x;
        return xf;
    }
    console.log(xf, yf, zf);
}

// 23을 에로
// 23 % 장군개미(5)의 나머지를 hp
// 3 % 병정개미(3)의 나머지를 hp
// 나눴을 때 0이면 몫을 더해 return 해줘야하기 때문에
// 몫을 담을 수 있는 박스를 생성해 넣음

코드가 너무 길어서 가독성이 떨어짐...
다른 분 코드를 살펴보았더니 이해도 잘되고 가독성 최고인 코드가 있었다.

function solution(hp) {
    const 장군개미 = Math.floor(hp / 5);
    const 병정개미 = Math.floor((hp - (장군개미 * 5)) / 3);
    const 일개미 = hp - ((장군개미 * 5) + (병정개미 * 3));
    return 장군개미+병정개미+일개미;
}
  1. 장군개미의 몫
  2. 병정개미는 hp에서 장군개미의 몫을 뺀 나머지를 / 3한 몫
  3. 일개미는 hp에서 장군개미와 병정개미의 몫을 뺀 나머지
  4. return 장군개미 몫 + 병정개미 몫 + 일개미의 몫

풀이를 보면서 간단하게 생각하라 수 있었는데 너무 어렵게 생각했던 거 같다.


모스부호(1)

모스부호 (1)

문제

머쓱이는 친구에게 모스부호를 이용한 편지를 받았습니다. 그냥은 읽을 수 없어 이를 해독하는 프로그램을 만들려고 합니다. 문자열 letter가 매개변수로 주어질 때, letter를 영어 소문자로 바꾼 문자열을 return 하도록 solution 함수를 완성해보세요.
모스부호는 다음과 같습니다.


function solution(letter) {
  	// 모스부호
    let morse =[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]
    // A ~ Z까지
    let eng = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
  	// 빈 배열
    let letterStr = [];
    // 공백을 기준으로 나눈다. 기존에 사용하던 스프레드 연산자는 안됨
    let str = letter.split(" ");
    console.log(str);
    
    let index;
    
    for(let i = 0; i < str.length; i++){
      	// 모스부호의 index 요소 중 같은게 있으면 
      	// 모스부호의 index 번호가 index로 들어감
        index = morse.indexOf(str[i]);
      	// 해당 eng[index]의 요소로 push
        letterStr.push(eng[index]);
    }
    console.log(letterStr);
    return letterStr.join('');
}

풀다보니 재미있었던 문제인 거 같다.


가위 바위 보

가위 바위 보

문제

가위는 2 바위는 0 보는 5로 표현합니다. 가위 바위 보를 내는 순서대로 나타낸 문자열 rsp가 매개변수로 주어질 때, rsp에 저장된 가위 바위 보를 모두 이기는 경우를 순서대로 나타낸 문자열을 return하도록 solution 함수를 완성해보세요.


function solution(rsp) {
    let game = rsp.split("");
    // x = 바위, y = 가위, z = 보
    let x = 0, y = 2, z = 5;
    let win = '';
    
    for(const i of game){
        switch(i){
            case '0':
                win += 5;
                break;
            case '2':
                win += 0
                break;
            case '5':
                win += 2;
                break;
        }
    }
    console.log(win);
    return win;
}

// 단순하게 생각해보면 경우의 수가 3개일 뿐
// 그 이유는 rsp가 0, 2, 5로 이루어져있다.
// 경우의 수 3개
// 바위(0)는 보(5)가 이김
// 가위(2)는 바위(0)가 이김
// 보(5)는 가위(2)가 이김

// for문으로 요소를 하나씩 꺼내 switch case로 
// 비교하면 쉽게 할 수 있을 거 같다.

구슬을 나누는 경우의 수

구슬을 나누는 경우의 수

문제

머쓱이는 구슬을 친구들에게 나누어주려고 합니다. 구슬은 모두 다르게 생겼습니다. 머쓱이가 갖고 있는 구슬의 개수 balls와 친구들에게 나누어 줄 구슬 개수 share이 매개변수로 주어질 때, balls개의 구슬 중 share개의 구슬을 고르는 가능한 모든 경우의 수를 return 하는 solution 함수를 완성해주세요.


힌트

서로 다른 경우의 수를 구하는 공식(순열)

서로 다른 경우의 수를 구하는 공식
factorial(n) / (factorial(n - m) * factorial(m))
// 서로 다른 경우의 수를 구하는 공식
// factorial(n) / (factorial(n - m) * factorial(m))

function solution(balls, share) {
    return factorial(balls) / (factorial(balls - share) * factorial(share));
}

function factorial(n) {
    let returnFactorial = BigInt(1);
    for(let i = n; i>= 1; i--){
        returnFactorial *= BigInt(i);
    }
    return returnFactorial;
}

어려웠던 점...

구슬을 나누는 경우의 수 문제가 가장 어려웠다.
1시간 동안 고민 해봤지만 모르겠어서 다른 분이 짜신 코드와 풀이를 보았다.
어떤 방식으로 진행되는 것이고 힌트에서 나와있듯이 공식을 이해한다면 문제는 쉽게 풀 수 있다는 것을 알게 되었다.

수학 공식처럼 풀어보니 할만 했다.

막상 문제는 풀었는데 계속 오류나서 검색해 봤더니 테스트케이스가 추가 된 이후 Number가 일정값을 넘어가면 문제가 생기는 것을 알게 되었다. 그래서 이 문제에 대해 블로그 글이 많았던 거 같다.

BigInt()를 사용해야 풀 수 있었다.

BigInt() - Number 원시 값이 안정적으로 나타낼 수 있는 최대치인 2^53 - 1보다 큰 정수를 표현할 수 있는 내장 객체이다.

초기값에 BigInt()를 주고 곱하면 해결할 수 있었다.

구슬을 나누는 경우의 수 참고한 블로그

구슬을 나누는 경우의 수 풀이

MDN - BigInt()

순열과 조합 알고리즘

profile
최선을 다해 꾸준히 노력하는 개발자 망고입니당 :D

0개의 댓글