본문 바로가기
Today I Learned 2024. 3. 7.

(24.03.07) Java 코딩 연습 문제 풀기 및 정리_04 👨‍💻

오늘도 연습 문제를 풀어보긴 했는데, 글이 길어지면 이해하기가 어려워져서 더 걸리는 것 같다.

한글 독해력이 이렇게 문제가 될 줄이야 자존감과 자신감이 동시에 떨어진다

 

그리고 github에 대해서 기록을 하라고 튜터님이 추천을 했기 때문에, 내일 이번주 마지막은 github에 대해 정리를 해야할 것

 


연습문제 풀어보기

Q1

더보기

어떤 게임에는 붕대 감기라는 기술이 있습니다.

붕대 감기는 t초 동안 붕대를 감으면서 1초마다 x만큼의 체력을 회복합니다. t초 연속으로 붕대를 감는 데 성공한다면 y만큼의 체력을 추가로 회복합니다. 게임 캐릭터에는 최대 체력이 존재해 현재 체력이 최대 체력보다 커지는 것은 불가능합니다.

기술을 쓰는 도중 몬스터에게 공격을 당하면 기술이 취소되고, 공격을 당하는 순간에는 체력을 회복할 수 없습니다. 몬스터에게 공격당해 기술이 취소당하거나 기술이 끝나면 그 즉시 붕대 감기를 다시 사용하며, 연속 성공 시간이 0으로 초기화됩니다.

몬스터의 공격을 받으면 정해진 피해량만큼 현재 체력이 줄어듭니다. 이때, 현재 체력이 0 이하가 되면 캐릭터가 죽으며 더 이상 체력을 회복할 수 없습니다.

당신은 붕대감기 기술의 정보, 캐릭터가 가진 최대 체력과 몬스터의 공격 패턴이 주어질 때 캐릭터가 끝까지 생존할 수 있는지 궁금합니다.

붕대 감기 기술의 시전 시간, 1초당 회복량, 추가 회복량을 담은 1차원 정수 배열 bandage와 최대 체력을 의미하는 정수 health, 몬스터의 공격 시간과 피해량을 담은 2차원 정수 배열 attacks가 매개변수로 주어집니다. 모든 공격이 끝난 직후 남은 체력을 return 하도록 solution 함수를 완성해 주세요. 만약 몬스터의 공격을 받고 캐릭터의 체력이 0 이하가 되어 죽는다면 -1을 return 해주세요.

import java.util.Arrays;

public class Practice {
    public static void main(String[] args) {
        int[] bandage = {5, 1, 5};
        int health = 30;
        int[][] attacks = {{2, 10}, {9, 15}, {10, 5}, {11, 5}};

        int chainattack = 0; //연속 공격 횟수
        int time = 0; // 총 시간
        int MAXhealth = health; // 최대 체력
        int attackcheck = 0;

        //마지막 공격 타이밍을 최대 시간까지 0초부터 반복
        for (time = 0; time <= attacks[attacks.length-1][0]; time++) {
            for (int[] attack : attacks) { // 각 공격 타이밍일 경우
                if (time == attack[0]) {
                    attackcheck = 1;
                    health -= attack[1];
                    chainattack = 0;
                }
            }

            if (health <= 0) { // 공격 받고, health 0이하일 경우, 즉시 종료
                health = -1;
                break;
            }

            if (attackcheck == 1) { // 공격 받았을 경우
                attackcheck = 0;
            } else { // 공격 안받았을 경우
                health += bandage[1]; // 초당 단위 회복

                chainattack++;
                if (chainattack == bandage[0]) { // 연속 회복 성공일 경우
                    health += bandage[2];
                    chainattack = 0;
                }
                if (health > MAXhealth) { // 최대체력 초과 불과
                    health = MAXhealth;

                }
            }
        }
        System.out.println(health);
    }
}

순서 정리 해보기

더보기

[붕대감기]
t초 동안 +x / 1초

t초 동안 연속 성공; +y 추가 회복

단, 최대체력 존재 그 이상 X

-

기술을 쓰는 도중;
몬스터 공격 : 기술 취소 & 최력 회복X
몬스터 공격 당한 후;
기술 취소/끝 ; 즉시 붕대감기 & 연속 성공 시간 0초기화

-

몬스터 공경 받을 때;
몬스터의 공격량 = 내가 피해받는양
체력이 0 이하 : 체력 회복X
-----

Q. 붕대감기 기술을 통해 주어진 조건을 가지고 시간에서 에서 살아남는가
 -> 살아남을 경우; 남은 체력 / 죽을 경우; -1 출력

매개변수
bandage 정수 배열 : 시전시간 t / 단위 회복량 x / 추가 회복량 y
최대체력 health 정수
attack 2차원 정수 배열 : ( 공격 시간, 피해량) x 여러개(시간에 한번씩

 

Self Feedback

  • 처음에 순서 바로 잡는건 좋았는데, 체력이 0이 되면 break해서 반복문을 빠져나가는게 전체 반복문인줄 착각, 매개변수에 따라서 그냥 공격받아도 회복시키는 경우가 생김
  • 중첩for 일 경우 break을 쓴다면 포함하는  for만 탈출하는 것 기억하기

 

 

Q2

더보기

각 칸마다 색이 칠해진 2차원 격자 보드판이 있습니다. 그중 한 칸을 골랐을 때, 위, 아래, 왼쪽, 오른쪽 칸 중 같은 색깔로 칠해진 칸의 개수를 구하려고 합니다.

보드의 각 칸에 칠해진 색깔 이름이 담긴 이차원 문자열 리스트 board와 고른 칸의 위치를 나타내는 두 정수 h, w가 주어질 때 board[h][w]와 이웃한 칸들 중 같은 색으로 칠해져 있는 칸의 개수를 return 하도록 solution 함수를 완성해 주세요.

import java.util.Arrays;

public class Practice2 {
    public static void main(String[] args) {
        String[][] board = {{"blue", "red", "orange", "red"}, {"red", "red", "blue", "orange"}, {"blue", "orange", "red", "red"}, {"orange", "orange", "red", "blue"}};
        int h = 1;
        int w = 1;

        int count = 0; // 총 색깔 갯수
        String pickcolor = board[h][w]; // 고른 좌표 색상

        //상하좌우 좌표
        int[][] around = new int[][]{{h - 1, w}, {h + 1, w}, {h, w - 1}, {h, w + 1}};

        //상화좌우 색상구하기
        for (int[] round_color : around) {
            if (round_color[0] >= 0 && round_color[0] <= board.length - 1 && round_color[1] >= 0 && round_color[1] <= board[0].length - 1) {
                if (board[round_color[0]][round_color[1]].equals(pickcolor)) {
                    count++;
                }
            }
        }
        System.out.println(count);
    }
}

순서 정리 해보기

더보기

[칸 갯수 구하기 조건]

board위의 어떤 칸이 골랐을 때;
상하좌우칸 중 같은 색 칸 갯수

[매개변수]
board 2차 배열 : 보드칸 칠해진 색깔 이름
board[h][w] 로 되어있음
h, w 정수 : 고른 칸 위치
h는 행, w는 열

[확인 과정 조건]
1. board 길이 저장
2. 같은 색 칸 갯수는 count

-
hw에 해당하는 색상 찾기
상하좌우 좌표 찾기
좌표 해당 색상 찾기
hw의 색상과 맞는지 확인
count에 더해서 출력

 

Q3

더보기

AI 엔지니어인 현식이는 데이터를 분석하는 작업을 진행하고 있습니다. 데이터는 ["코드 번호(code)", "제조일(date)", "최대 수량(maximum)", "현재 수량(remain)"]으로 구성되어 있으며 현식이는 이 데이터들 중 조건을 만족하는 데이터만 뽑아서 정렬하려 합니다.

예를 들어 다음과 같이 데이터가 주어진다면

data = [[1, 20300104, 100, 80], [2, 20300804, 847, 37], [3, 20300401, 10, 8]]
이 데이터는 다음 표처럼 나타낼 수 있습니다.

code date maximum remain
1 20300104 100 80
2 20300804 847 37
3 20300401 10 8
주어진 데이터 중 "제조일이 20300501 이전인 물건들을 현재 수량이 적은 순서"로 정렬해야 한다면 조건에 맞게 가공된 데이터는 다음과 같습니다.

data = [[3,20300401,10,8],[1,20300104,100,80]]
정렬한 데이터들이 담긴 이차원 정수 리스트 data와 어떤 정보를 기준으로 데이터를 뽑아낼지를 의미하는 문자열 ext, 뽑아낼 정보의 기준값을 나타내는 정수 val_ext, 정보를 정렬할 기준이 되는 문자열 sort_by가 주어집니다.

data에서 ext 값이 val_ext보다 작은 데이터만 뽑은 후, sort_by에 해당하는 값을 기준으로 오름차순으로 정렬하여 return 하도록 solution 함수를 완성해 주세요. 단, 조건을 만족하는 데이터는 항상 한 개 이상 존재합니다.

import java.util.Arrays;

public class Practice {
    public static void main(String[] args) {
        int[][] data = {{1, 20300104, 100, 80}, {2, 20300804, 847, 37}, {3, 20300401, 10, 8}};
        String ext = "data";
        int val_ext = 20300501;
        String sort_by = "remain";


        int standard = 0;
        int sort_standard = 0;
        int order_standard = 0; // ext 를 data 인덱스값 열중 어떤걸 고를지 만들어줌
        switch (ext) {
            case "code":
                standard = 0;
                break;
            case "data":
                standard = 1;
                break;
            case "maximum":
                standard = 2;
                break;
            case "remain":
                standard = 3;
                break;
        }

        switch (sort_by) {
            case "code":
                sort_standard = 0;
                break;
            case "data":
                sort_standard = 1;
                break;
            case "maximum":
                sort_standard = 2;
                break;
            case "remain":
                sort_standard = 3;
                break;
        }

        int[][] result = new int[data.length][data[0].length];
        int total = 0;
        //기준 미만 data 를 조건에 result배열에 sortby 해당 값 지정
        for (int i = 0; i < data.length; i++) {
            if (data[i][standard] < val_ext) {
                result[i] = data[i];
                total++;
            }
        }

        // 특정 열=sort_standard을 기준으로 정렬
        for (int i = 0; i < result.length; i++) {
            for (int j = 0; j < result.length; j++) {
                if (result[i][sort_standard] < result[j][sort_standard]) {
                    //스와핑
                    int[] temp = result[i];
                    result[i] = result[j];
                    result[j] = temp;
                }

            }
        }
        // 0,0,0,0 배열 제외하고 return
        int[][] final_result = new int[total][result[0].length];
        int j = 0;
        for (int i = 0; i < result.length; i++) {

            if (result[i][sort_standard] == 0) {
                continue;

            } else {
                final_result[j] = result[i];
                j++;

            }

        }
        System.out.println(Arrays.deepToString(final_result));
    }
}

 

스와핑

if (result[i][sort_standard] < result[j][sort_standard]) {
                    //스와핑
                    int[] temp = result[i];
                    result[i] = result[j];
                    result[j] = temp;
  • 두 인덱스값 사이의 조건에 부합 할때,  배열에서 temp라는 변수를 정해서 거기에 미리 첫 인덱스를 저장을 하고, 두번째 인덱스를 첫번쨰 인덱스로 지정, 두번째 인덱스를 temp로 저장을 하면 두 인덱스의 데이터 값이 바꿀 수 있음