[20221230] 코딩테스트 스터디

6720·2022년 12월 29일
post-thumbnail

👨‍🏫 이번 목표

프로그래머스 코딩테스트 입문 Java로 Day 9 수학, 문자열, 해시, 완전탐색, 조건문, Day 10 조건문, 배열, 수학, 시뮬레이션 풀기

📒 문제 풀이 (Day 9 수학, 문자열, 해시, 완전탐색, 조건문)

개미군단

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

제한사항

  • hp는 자연수입니다.
  • 0 ≤ hp ≤ 1000

입출력 예

hpresult
235
246
999201
class Solution {
    public int solution(int hp) {
        int answer = 0;
        int general = 5, soldier = 3, ergate = 1;
        answer = (hp / general) + (hp % general / soldier) + (hp % general % soldier / ergate);
        
        return answer;
    }
}

1) general의 공격력 5 / soldier의 공격력 3 / ergate의 공격력 1

2) hp에서 general에 대한 계산을 끝내면 남은 hphp % general임.

hp를 통해 다시 soldier과 계산함. 그러면 hphp % general % soldier이 됨.

hp를 가지고 마지막으로 ergate에 대한 계산을 해주면 됨.

모스부호 (1)

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

모스부호는 다음과 같습니다.

morse = { 
    '.-':'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'
}

제한사항

  • 1 ≤ letter의 길이 ≤ 1,000
  • return값은 소문자입니다.
  • letter의 모스부호는 공백으로 나누어져 있습니다.
  • letter에 공백은 연속으로 두 개 이상 존재하지 않습니다.
  • 해독할 수 없는 편지는 주어지지 않습니다.
  • 편지의 시작과 끝에는 공백이 없습니다.

입출력 예

letterresult
".... . .-.. .-.. ---""hello"
".--. -.-- - .... --- -.""python"
import java.util.Arrays;

class Solution {
    public String solution(String letter) {
        String answer = "";
        String[] morse = {
            ".-", "-...", "-.-.", "-..", ".", "..-.",
            "--.", "....", "..", ".---", "-.-", ".-..",
            "--", "-.", "---", ".--.", "--.-", ".-.",
            "...", "-", "..-", "...-", ".--", "-..-",
            "-.--", "--.."
        };
        String[] str = letter.split("\\s");
        
        for (int i = 0; i < str.length; i++) {
            for (int j = 0; j < morse.length;j++) {
                if (morse[j].equals(str[i])) {
                    answer = "" + answer + (char)(j+97);
                    break;
                }
            }
        }
        
        return answer;
    }
}

프로그래머스는 자바를 배려해주지 않는다 ㅡㅡ

가위 바위 보

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

제한사항

  • 0 < rsp의 길이 ≤ 100
  • rsp와 길이가 같은 문자열을 return 합니다.
  • rsp는 숫자 0, 2, 5로 이루어져 있습니다.

입출력 예

rspresult
"2""0"
"205""052"
class Solution {
    public String solution(String rsp) {
        String answer = "";
                
        for (int i = 0; i < rsp.length(); i++) {
            switch (rsp.charAt(i)) {
                case ('2'):
                    answer = "" + answer + "0";
                    break;
                case ('0'):
                    answer = "" + answer + "5";
                    break;
                case ('5'):
                    answer = "" + answer + "2";
                    break;
            }
        }
        
        return answer;
    }
}

구슬을 나누는 경우의 수

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

제한사항

  • 1 ≤ balls ≤ 30
  • 1 ≤ share ≤ 30
  • 구슬을 고르는 순서는 고려하지 않습니다.
  • share ≤ balls

입출력 예

ballsshareresult
323
5310

Hint

  • 서로 다른 n개 중 m개를 뽑는 경우의 수 공식은 다음과 같습니다. n!(nm)!×m!\frac{n!}{(n-m)! \times m!}
class Solution {
    public int solution(int balls, int share) {
        int answer = 0;
        
        answer = factorial(balls) / (factorial(balls - share) * factorial(share));
         
        return answer;
    }
    
    public int factorial(int num) {
        int result = 1;
        for (int i = 1; i <= num; i++) {
            result *= i; 
        }
        return result;
    }
}

로 했는데 30!이 30자리가 넘는다고 해서 long으로도 커버가 불가능하다고 한다.

import java.math.BigInteger;

class Solution {
    public BigInteger solution(int balls, int share) {
        BigInteger answer = new BigInteger("0");
        BigInteger[] factorial = new BigInteger[balls+1];
        factorial[0] = new BigInteger("1");;
        factorial[1] = new BigInteger("1");;

        for (int i = 2; i <= balls; i++) {
            factorial[i] = factorial[i-1].multiply(new BigInteger(Integer.toString(i)));
        }
        
        return (factorial[balls].divide(factorial[balls-share].multiply(factorial[share])));
    }
}

참고 링크

우선 슬슬 다른 분의 코드를 적어서 BigInteger가 어떤식으로 동작하는지 확인했다. 한번 적어보니 역시 프로그래머스는 자바를 배려하지 않는다.

import java.math.BigInteger;

class Solution {
    public BigInteger solution(int balls, int share) {
        BigInteger answer = new BigInteger("0");      
        
        answer = factorial(balls).divide(factorial(balls - share).multiply(factorial(share)));
         
        return answer;
    }
    
    public BigInteger factorial(int num) {
        BigInteger result = new BigInteger("1");
        if (num == 0 | num == 1) return result;
        for (int i = 2; i <= num; i++) {
            result = result.multiply(new BigInteger(Integer.toString(i)));
        }
        return result;
    }
}

1) BigInteger는 int나 long을 그대로 받아들이지 못하고 String으로 변환해줘야 선언이 가능함.

BigInteger answer = new BigInteger("0")

new BigInteger(Integer.toString(i))

2) BigInteger는 기본적인 연산이 불가능하여 multiply()divide()를 사용하여 계산해야 함.

📒 문제 풀이 (Day 10 조건문, 배열, 수학, 시뮬레이션)

점의 위치 구하기

사분면은 한 평면을 x축과 y축을 기준으로 나눈 네 부분입니다. 사분면은 아래와 같이 1부터 4까지 번호를매깁니다.

  • x 좌표와 y 좌표가 모두 양수이면 제1사분면에 속합니다.
  • x 좌표가 음수, y 좌표가 양수이면 제2사분면에 속합니다.
  • x 좌표와 y 좌표가 모두 음수이면 제3사분면에 속합니다.
  • x 좌표가 양수, y 좌표가 음수이면 제4사분면에 속합니다.

x 좌표 (x, y)를 차례대로 담은 정수 배열 dot이 매개변수로 주어집니다. 좌표 dot이 사분면 중 어디에 속하는지 1, 2, 3, 4 중 하나를 return 하도록 solution 함수를 완성해주세요.

제한사항

  • dot의 길이 = 2
  • dot[0]은 x좌표를, dot[1]은 y좌표를 나타냅니다
  • 500 ≤ dot의 원소 ≤ 500
  • dot의 원소는 0이 아닙니다.

입출력 예

dotresult
[2, 4]1
[-7, 9]2
class Solution {
    public int solution(int[] dot) {
        int answer = 0;
        
        if (dot[0] > 0) {
            if (dot[1] > 0) answer = 1;
            else answer = 4;
        } else {
            if (dot[1] > 0) answer = 2;
            else answer = 3;
        }
        
        return answer;
    }
}

2차원으로 만들기

정수 배열 num_list와 정수 n이 매개변수로 주어집니다. num_list를 다음 설명과 같이 2차원 배열로 바꿔 return하도록 solution 함수를 완성해주세요.

num_list가 [1, 2, 3, 4, 5, 6, 7, 8] 로 길이가 8이고 n이 2이므로 num_list를 2 * 4 배열로 다음과 같이 변경합니다. 2차원으로 바꿀 때에는 num_list의 원소들을 앞에서부터 n개씩 나눠 2차원 배열로 변경합니다.

num_listnresult
[1, 2, 3, 4, 5, 6, 7, 8]2[[1, 2], [3, 4], [5, 6], [7, 8]]

제한사항

  • num_list의 길이는 n의 배 수개입니다.
  • 0 ≤ num_list의 길이 ≤ 150
  • 2 ≤ n < num_list의 길이

입출력 예

num_listnresult
[1, 2, 3, 4, 5, 6, 7, 8]2[[1, 2], [3, 4], [5, 6], [7, 8]]
[100, 95, 2, 4, 5, 6, 18, 33, 948]3[[100, 95, 2], [4, 5, 6], [18, 33, 948]]
class Solution {
    public int[][] solution(int[] num_list, int n) {
        int[][] answer = new int[num_list.length/n][n];
        int count = 0;
        
        for (int i = 0; i < (num_list.length/n); i++) {
            for (int j = 0; j < n; j++) {
                answer[i][j] = num_list[count];
                count++;
            }
        } 
        
        return answer;
    }
}

공 던지기

머쓱이는 친구들과 동그랗게 서서 공 던지기 게임을 하고 있습니다. 공은 1번부터 던지며 오른쪽으로 한 명을 건너뛰고 그다음 사람에게만 던질 수 있습니다. 친구들의 번호가 들어있는 정수 배열 numbers와 정수 K가 주어질 때, k번째로 공을 던지는 사람의 번호는 무엇인지 return 하도록 solution 함수를 완성해보세요.

제한사항

  • 2 < numbers의 길이 < 100
  • 0 < k < 1,000
  • numbers의 첫 번째와 마지막 번호는 실제로 바로 옆에 있습니다.
  • numbers는 1부터 시작하며 번호는 순서대로 올라갑니다.

입출력 예

numberskresult
[1, 2, 3, 4]23
[1, 2, 3, 4, 5, 6]53
[1, 2, 3]32
class Solution {
    public int solution(int[] numbers, int k) {
        int answer = 0, count = 0;
        
        for (int i = 0; i < k; i++) {
            if (count >= numbers.length) count -= numbers.length;
            answer = numbers[count];
            count+=2;
        }
        
        return answer;
    }
}

배열 회전시키기

정수가 담긴 배열 numbers와 문자열 direction가 매개변수로 주어집니다. 배열 numbers의 원소를 direction방향으로 한 칸씩 회전시킨 배열을 return하도록 solution 함수를 완성해주세요.

제한사항

  • 3 ≤ numbers의 길이 ≤ 20
  • direction은 "left" 와 "right" 둘 중 하나입니다.

입출력 예

numbersdirectionresult
[1, 2, 3]"right"[3, 1, 2]
[4, 455, 6, 4, -1, 45, 6]"left"[455, 6, 4, -1, 45, 6, 4]
class Solution {
    public int[] solution(int[] numbers, String direction) {
        int[] answer = new int[numbers.length];
        int count = 0;

        if (direction.equals("right")) count = numbers.length - 1;
        else if (direction.equals("left")) count = 1;

        for (int i = 0; i < numbers.length; i++) {
            if (count >= numbers.length) count = count - numbers.length;
            answer[i] = numbers[count];
            count++;
        }
        return answer;
    }
}

✨ 후기

1) 이제 하루에 하루치만 풀게돼서 다른 공부할 시간이 늘어날 듯하다. 그 시간에 자바 문법정리나 해야겠다.

2) 기록표

profile
뭐라도 하자

0개의 댓글