본문 바로가기

항해 99/Java

페어 프로그래밍 - 코딩 테스트 5

코드 리뷰 - ChatGPT

 

44. 2016년

페어 프로그래밍 코드

package pair5;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.Locale;
/**
 * 2016년
 * 2016년 1월 1일은 금요일입니다.
 * 2016년 a월 b일은 무슨 요일일까요?
 * 두 수 a ,b를 입력받아 2016년 a월 b일이 무슨 요일인지 리턴하는 함수, `solution`을 완성하세요.
 */
public class Calender {
    // [31 29 31 30 31 30 31 31 30 31 30 31]
    // a = 월, b = 일
    // 1월 1일 = 금
    // 1월 8일 = 금 ... 29일 = 금
    // 2월 5일 = 금
    private static String solution(int a, int b) {
        String answer = "";
        int[] days = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        String[] week = {"THU", "FRI", "SAT", "SUN", "MON", "TUE", "WED"};

        int sum = 0;
        for (int i=0; i<a-1; i++) {
            sum += days[i];
        }
        sum += b;

        int remain = sum % 7;
        answer = week[remain];

        return answer;
    }

	// 다른 방법
    // 2016년에서 사용자가 a : 월, b : 일
        public static String getDayOfWeekUpperCase(int month, int day) {
            // LocalDate 객체 생성
            LocalDate date = LocalDate.of(2016, month, day);

            // 요일 정보를 가져옴
            DayOfWeek dayOfWeek = date.getDayOfWeek();

            // 요일 정보를 short 형식으로 받고, 모두 대문자로 변환
            String dayOfWeekShortUpperCase = dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.US).toUpperCase();

            return dayOfWeekShortUpperCase;
        }

    public static void main(String[] args) {
        System.out.println(getDayOfWeekUpperCase(2,6));
        String answer = Calender.solution(5, 24);
        System.out.println(getDayOfWeekUpperCase(2,6));
    }
}

 

코드 리뷰

  • 가독성
    • 코드는 매우 간결하고 이해하기 쉽습니다. 변수 이름이 명확하고, 주석도 적절하게 사용되었습니다.
    • LocalDate와 DayOfWeek 클래스를 사용하여 날짜와 요일을 처리하는 방법은 자바에서 날짜와 시간을 다룰 때의 표준 접근 방식입니다.
  • 성능
    • 성능에 대한 우려는 거의 없습니다. 이 코드는 단일 연산에서 실행되며, LocalDate 클래스는 날짜 관련 계산을 위해 최적화되어 있습니다.
    • 이 경우 성능 최적화를 위해 변경할 수 있는 부분은 별로 없으며, 제공된 입력 범위 내에서 코드는 매우 효율적으로 실행될 것입니다.
  • 확장성과 유지보수
    • 이 함수는 2016년 한 해에만 국한되어 있으며, 다른 연도의 날짜를 처리하도록 확장하려면 연도를 매개변수로 추가하는 등 코드 수정이 필요합니다.
    • 유지보수 측면에서 코드는 매우 깔끔하고 잘 구조화되어 있어, 필요한 변경이나 확장이 용이합니다.
  • 개선사항
    • TextStyle.SHORT 대신 TextStyle.FULL을 사용하여 요일을 전체 이름으로 반환하도록 변경할 수 있지만, 문제 요구 사항에 따라 SHORT 형식이 적절합니다.
    • 코드의 유연성을 높이고자 한다면, Locale을 하드코딩하는 대신 함수의 매개변수로부터 받을 수 있도록 하는 것도 고려할 수 있습니다. 이렇게 하면 다른 로케일에 대해서도 코드를 사용할 수 있게 됩니다.

 

 

 

45. 카드 뭉치

페어 프로그래밍 코드

package pair5;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.LinkedList;
import java.util.Queue;

/**
 * 카드 뭉치
 * 원하는 카드 뭉치에서 카드를 순서대로 한 장씩 사용합니다.
 * 한 번 사용한 카드는 다시 사용할 수 없습니다.
 * 카드를 사용하지 않고 다음 카드로 넘어갈 수 없습니다.
 * 기존에 주어진 카드 뭉치의 단어 순서는 바꿀 수 없습니다.
 *
 * 문자열로 이루어진 배열 cards1, cards2와 원하는 단어 배열 goal이 매개변수로 주어질 때,
 * cards1과 cards2에 적힌 단어들로
 * goal를 만들 있다면 "Yes"를, 만들 수 없다면 "No"를
 * return하는 solution 함수를 완성해주세요.
 */
public class PackOfCards {
    private static String solution(String[] cards1, String[] cards2, String[] goal) {
        String answer = "Yes";
        List<String> cardsList1 = new ArrayList<>(Arrays.asList(cards1));
        List<String> cardsList2 = new ArrayList<>(Arrays.asList(cards2));

        for (int i=0; i<goal.length; i++) {
            if (!cardsList1.isEmpty() && cardsList1.get(0).equals(goal[i])) {
                cardsList1.remove(goal[i]);
            } else if (!cardsList2.isEmpty() && cardsList2.get(0).equals(goal[i])) {
                cardsList2.remove(goal[i]);
            } else {
                return "No";
            }
        }

		// Queue 사용 방법
        // cards1, cards2를 Queue로 변환
//        Queue<String> card1 = new LinkedList<>(Arrays.asList(cards1));
//        Queue<String> card2 = new LinkedList<>(Arrays.asList(cards2));
//
//        for (int i = 0; i < goal.length; i++) {
//            if (!card1.isEmpty() && card1.peek().equals(goal[i])) {
//                card1.poll();
//            } else if (!card2.isEmpty() && card2.peek().equals(goal[i])) {
//                card2.poll();
//            } else {
//                return "No";
//            }
//        }

        return answer;
    }

    public static void main(String[] args) {
        String[] cards1 = {"i", "drink", "water"};
        String[] cards2 = {"want", "to"};
        String[] goal = {"i", "want", "to", "drink", "water"};
        String answer = solution(cards1, cards2, goal);
        System.out.println(answer);
    }
}

 

코드 리뷰

  • 가독성
    • 변수명과 메소드 구조가 명확하며, 주석이나 추가 설명 없이도 코드의 의도와 로직을 이해하기 쉽습니다.
    • Queue 인터페이스를 사용하여 카드 뭉치를 관리하는 방식은 이 문제에 적합하며, poll() 메소드를 사용해 카드를 순서대로 처리하는 로직이 직관적입니다.
  • 성능
    • LinkedList를 사용한 Queue 구현은 이 경우에 적절합니다. 각 카드를 확인하고 제거하는데 상수 시간(O(1))이 소요되므로, 전체적인 성능은 좋습니다.
    • 전체 로직은 goal 배열의 길이에 비례하는 시간복잡도를 가집니다(O(n)), 여기서 n은 goal 배열의 길이입니다. 이는 주어진 문제를 해결하는 데 있어 효율적입니다.
  • 확장성과 유지보수
    • 코드는 주어진 문제에 특화되어 있으며, 다른 유형의 카드 게임이나 더 복잡한 규칙에 적용하려면 수정이 필요할 수 있습니다. 그러나 현재 형태로는 문제 요구사항을 잘 충족합니다.
    • 유지보수 측면에서, 변수와 로직이 간결하므로 필요한 변경을 적용하기 쉬울 것입니다.
  • 개선사항
    • 코드는 이미 깔끔하고 효율적으로 작성되어 있어서, 기능적인 측면에서의 개선점은 크게 보이지 않습니다.
    • 더 복잡한 시나리오를 고려하지 않는 이상, 현재 로직의 구조를 변경할 필요는 없어 보입니다.
    • 다만, 문제의 복잡도나 요구사항이 확장될 경우, 예를 들어 카드를 건너뛰거나 다시 사용할 수 있는 규칙이 추가된다면, 현재 로직을 조정하거나 새로운 데이터 구조를 도입해야 할 수 있습니다.

 

 

 

46. 과일 장수

페어 프로그래밍 코드

package pair5;

import java.util.Arrays;

public class Fruit {
    /**
     * 과일 장수
     * 사과 1개의 점수 = k
     * 상자 1개당 사과 개수 = m
     * 상자에 들어 있는 가장 낮은 점수의 사과 = p
     * 1개의 상자 가격 = p * m
     * 각가의 사과의 점수 배열 = score
     * [1,1,1,2,2,3,3]
     */
    public static int solution(int k, int m, int[] score) {
        int answer = 0;
        Arrays.sort(score); // 사과 점수 별 오름차순
        
        for (int i = score.length-1; i >= m-1; i -= m) {
            answer += score[i-m+1] * m;
        }
        return answer;
    }

    public static void main(String[] args) {
//        int[] score = {1, 2, 3, 1, 2, 3, 1};
        int[] score = {4, 1, 2, 2, 4, 4, 4, 4, 1, 2, 4, 2};
        System.out.println(solution(4, 3, score));
    }
}

 

코드 리뷰

  • 문제점
    • .잘못된 최소 점수 계산: 코드에서 min 변수는 사용되지 않습니다. 이 변수는 원래 상자에 담긴 사과 중 가장 낮은 점수를 의미하는 것 같지만, 실제 계산에는 영향을 주지 않습니다.

 

 

 

47. 모의고사 완전 탐색

페어 프로그래밍 코드

package test3;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test47 {
    public static int[] solution(int[] answers) {
        int[] one = {1, 2, 3, 4, 5};
        int[] two = {2, 1, 2, 3, 2, 4, 2, 5};
        int[] three = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};

        int oneCnt = 0;
        int twoCnt = 0;
        int threeCnt = 0;
        for (int i = 0; i < answers.length; i++) {
            if (answers[i] == one[i % one.length]) oneCnt++;
            if (answers[i] == two[i % two.length]) twoCnt++;
            if (answers[i] == three[i % three.length]) threeCnt++;
        }

        int[] arr = new int[]{oneCnt, twoCnt, threeCnt};
        Arrays.sort(arr);

        int max = arr[2];
        List<Integer> list = new ArrayList<>();
        if (oneCnt == max) list.add(1);
        if (twoCnt == max) list.add(2);
        if (threeCnt == max) list.add(3);

        int[] answer = list.stream().mapToInt(i -> i).toArray();
        return answer;
    }
}

 

코드 리뷰

  • 가독성
    • 코드는 매우 간결하고 명확합니다. 변수 이름(one, two, three, oneCnt, twoCnt, threeCnt)은 각각의 용도를 잘 나타내며, 코드의 의도를 쉽게 이해할 수 있도록 돕습니다.
    • 반복문과 조건문은 명확하게 구성되어 있어, 각 수포자가 어떻게 답안을 찍는지와 이를 어떻게 카운팅하는지 쉽게 파악할 수 있습니다.
  • 성능
    • 반복문과 조건문은 명확하게 구성되어 있어, 각 수포자가 어떻게 답안을 찍는지와 이를 어떻게 카운팅하는지 쉽게 파악할 수 있습니다.
  • 확장성
    • 현재 코드는 특정한 패턴(one, two, three)과 고정된 수포자 수(3명)에 맞춰져 있습니다. 만약 추가적인 수포자가 등장하거나 패턴이 변경될 경우, 새로운 배열을 추가하고 로직에 반영해야 합니다.
    • 확장성을 높이기 위해, 수포자의 답안 패턴을 관리하는 별도의 클래스나 구조체를 도입하고, 이를 일반화하여 관리할 수 있는 방법을 고려할 수 있습니다.
  • 유지보수
    • 코드의 구조가 단순하고 명확하기 때문에 유지 보수 측면에서 유리합니다. 새로운 요구 사항이나 변경 사항이 생겼을 때, 관련 로직을 쉽게 수정하거나 추가할 수 있습니다.
    • 하지만, 수포자의 답안 패턴이 변경되거나 새로운 수포자가 추가될 경우, 코드를 직접 수정해야 합니다. 이러한 변경에 더 유연하게 대응하기 위해, 답안 패턴을 외부 데이터로부터 동적으로 로딩하는 방법 등을 고려할 수 있습니다.
  • 개선사항
    • 정답을 카운트하고 최대값을 찾는 과정에서 arr 배열을 정렬하는 대신, 처음부터 최대값을 계산할 수 있습니다. 이는 불필요한 정렬 과정을 제거하여 효율성을 높입니다.
    • 최대 점수를 받은 사람을 찾는 과정에서 정렬된 arr 배열을 사용하는 대신, 직접 oneCnt, twoCnt, threeCnt를 비교하여 최대값을 결정할 수 있습니다.

개선 코드

import java.util.ArrayList;

class Solution {
    public int[] solution(int[] answers) {
        int[] one = {1, 2, 3, 4, 5};
        int[] two = {2, 1, 2, 3, 2, 4, 2, 5};
        int[] three = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
        
        int oneCnt = 0;
        int twoCnt = 0;
        int threeCnt = 0;
        for (int i = 0; i < answers.length; i++) {
            if (answers[i] == one[i % one.length]) oneCnt++;
            if (answers[i] == two[i % two.length]) twoCnt++;
            if (answers[i] == three[i % three.length]) threeCnt++;
        }

        int max = Math.max(oneCnt, Math.max(twoCnt, threeCnt));
        ArrayList<Integer> list = new ArrayList<>();
        if (oneCnt == max) list.add(1);
        if (twoCnt == max) list.add(2);
        if (threeCnt == max) list.add(3);

        return list.stream().mapToInt(i -> i).toArray();
    }
}

'항해 99 > Java' 카테고리의 다른 글

Java - 프로세스, 쓰레드  (0) 2024.02.19
WIL - 2  (0) 2024.02.18
Java - 오류 및 예외 처리, 제네릭, Collection  (1) 2024.02.17
페어 프로그래밍 - 코딩 테스트 4  (1) 2024.02.16
페어 프로그래밍 - 코딩 테스트 3  (0) 2024.02.15